mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2026-11-01 01:01:31 +01:00
Merge branch 'main' into feature/cuda_clusterfinder
This commit is contained in:
commit
7c91ce99c2
44 files changed
+4251
-3801
No files matched your search
@@ -0,0 +1,12 @@
|
||||
name: pre-commit
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
pre-commit:
|
||||
name: pre-commit
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: pre-commit/action@v3.0.1
|
||||
+186
-16
@@ -1,25 +1,195 @@
|
||||
install/
|
||||
.cproject
|
||||
.project
|
||||
bin/
|
||||
.settings
|
||||
*.aux
|
||||
*.log
|
||||
*.out
|
||||
*.toc
|
||||
# C++ .gitignore template (https://github.com/github/gitignore/blob/main/C%2B%2B.gitignore)
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Linker files
|
||||
*.ilk
|
||||
|
||||
# Debugger Files
|
||||
*.pdb
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
.*
|
||||
*.dylib
|
||||
*.dll
|
||||
*.so.*
|
||||
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# Build directories
|
||||
build/
|
||||
RELEASE.txt
|
||||
Build/
|
||||
build-*/
|
||||
|
||||
# CMake generated files
|
||||
CMakeFiles/
|
||||
CMakeCache.txt
|
||||
cmake_install.cmake
|
||||
Makefile
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
|
||||
# Temporary files
|
||||
*.tmp
|
||||
*.log
|
||||
*.bak
|
||||
*.swp
|
||||
|
||||
# vcpkg
|
||||
vcpkg_installed/
|
||||
|
||||
# debug information files
|
||||
*.dwo
|
||||
|
||||
# test output & cache
|
||||
Testing/
|
||||
.cache/
|
||||
|
||||
ctbDict.cpp
|
||||
ctbDict.h
|
||||
# Python .gitignore template (https://github.com/github/gitignore/blob/main/Python.gitignore)
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[codz]
|
||||
*$py.class
|
||||
|
||||
wheelhouse/
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
*.pyc
|
||||
*/__pycache__/*
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py.cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.envrc
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# Visual Studio Code
|
||||
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
||||
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
||||
# you could uncomment the following to ignore the entire vscode folder
|
||||
.vscode/
|
||||
|
||||
# Ruff stuff:
|
||||
.ruff_cache/
|
||||
|
||||
# user defined
|
||||
wheelhouse/
|
||||
@@ -0,0 +1,29 @@
|
||||
fail_fast: true
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v6.0.0
|
||||
hooks:
|
||||
- id: check-added-large-files
|
||||
- id: check-yaml
|
||||
exclude: conda-recipe/
|
||||
- id: check-toml
|
||||
- id: check-json
|
||||
- id: mixed-line-ending
|
||||
|
||||
- repo: https://github.com/crate-ci/typos
|
||||
rev: v1.45.0
|
||||
hooks:
|
||||
- id: typos
|
||||
files: docs
|
||||
args: [] # empty, to remove write-changes from the default arguments.
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||
rev: v22.1.3
|
||||
hooks:
|
||||
- id: clang-format
|
||||
name: clang-format .cpp and .hpp files
|
||||
|
||||
- repo: https://github.com/zultron/cmake-format-precommit
|
||||
rev: v0.6.14
|
||||
hooks:
|
||||
- id: cmake-format
|
||||
+330
-300
@@ -1,11 +1,11 @@
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
project(aare
|
||||
DESCRIPTION "Data processing library for PSI detectors"
|
||||
HOMEPAGE_URL "https://github.com/slsdetectorgroup/aare"
|
||||
LANGUAGES C CXX
|
||||
)
|
||||
project(
|
||||
aare
|
||||
DESCRIPTION "Data processing library for PSI detectors"
|
||||
HOMEPAGE_URL "https://github.com/slsdetectorgroup/aare"
|
||||
LANGUAGES C CXX)
|
||||
|
||||
# Read VERSION file into project version
|
||||
set(VERSION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/VERSION")
|
||||
@@ -13,37 +13,34 @@ file(READ "${VERSION_FILE}" VERSION_CONTENT)
|
||||
string(STRIP "${VERSION_CONTENT}" PROJECT_VERSION_STRING)
|
||||
set(PROJECT_VERSION ${PROJECT_VERSION_STRING})
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
execute_process(
|
||||
COMMAND git log -1 --format=%h
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||
OUTPUT_VARIABLE GIT_HASH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
COMMAND git log -1 --format=%h
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||
OUTPUT_VARIABLE GIT_HASH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
message(STATUS "Building from git hash: ${GIT_HASH}")
|
||||
|
||||
if (${CMAKE_VERSION} VERSION_GREATER "3.24")
|
||||
cmake_policy(SET CMP0135 NEW) #Fetch content download timestamp
|
||||
if(${CMAKE_VERSION} VERSION_GREATER "3.24")
|
||||
cmake_policy(SET CMP0135 NEW) # Fetch content download timestamp
|
||||
endif()
|
||||
cmake_policy(SET CMP0079 NEW)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
include(FetchContent)
|
||||
|
||||
#Set default build type if none was specified
|
||||
# Set default build type if none was specified
|
||||
include(cmake/helpers.cmake)
|
||||
|
||||
|
||||
default_build_type("Release")
|
||||
set_std_fs_lib()
|
||||
message(STATUS "Extra linking to fs lib:${STD_FS_LIB}")
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||
|
||||
|
||||
# General options
|
||||
option(AARE_PYTHON_BINDINGS "Build python bindings" OFF)
|
||||
option(AARE_TESTS "Build tests" OFF)
|
||||
@@ -53,7 +50,10 @@ option(AARE_IN_GITHUB_ACTIONS "Running in Github Actions" OFF)
|
||||
option(AARE_DOCS "Build documentation" OFF)
|
||||
option(AARE_VERBOSE "Verbose output" OFF)
|
||||
option(AARE_CUSTOM_ASSERT "Use custom assert" OFF)
|
||||
option(AARE_INSTALL_PYTHONEXT "Install the python extension in the install tree under CMAKE_INSTALL_PREFIX/aare/" OFF)
|
||||
option(
|
||||
AARE_INSTALL_PYTHONEXT
|
||||
"Install the python extension in the install tree under CMAKE_INSTALL_PREFIX/aare/"
|
||||
OFF)
|
||||
option(AARE_ASAN "Enable AddressSanitizer" OFF)
|
||||
|
||||
option(AARE_CUDA "Build CUDA cluster finder backend" OFF)
|
||||
@@ -69,18 +69,46 @@ option(AARE_FETCH_ZMQ "Use FetchContent to download libzmq" ON)
|
||||
option(AARE_FETCH_LMFIT "Use FetchContent to download lmfit" ON)
|
||||
option(AARE_FETCH_MINUIT2 "Use FetchContent to download Minuit2" ON)
|
||||
|
||||
|
||||
#Convenience option to use system libraries only (no FetchContent)
|
||||
# Convenience option to use system libraries only (no FetchContent)
|
||||
option(AARE_SYSTEM_LIBRARIES "Use system libraries" OFF)
|
||||
if(AARE_SYSTEM_LIBRARIES)
|
||||
message(STATUS "Build using system libraries")
|
||||
set(AARE_FETCH_FMT OFF CACHE BOOL "Disabled FetchContent for FMT" FORCE)
|
||||
set(AARE_FETCH_PYBIND11 OFF CACHE BOOL "Disabled FetchContent for pybind11" FORCE)
|
||||
set(AARE_FETCH_CATCH OFF CACHE BOOL "Disabled FetchContent for catch2" FORCE)
|
||||
set(AARE_FETCH_JSON OFF CACHE BOOL "Disabled FetchContent for nlohmann::json" FORCE)
|
||||
set(AARE_FETCH_ZMQ OFF CACHE BOOL "Disabled FetchContent for libzmq" FORCE)
|
||||
# Still fetch lmfit and Minuit2 when setting AARE_SYSTEM_LIBRARIES
|
||||
# since these are not available on conda-forge
|
||||
set(AARE_FETCH_FMT
|
||||
OFF
|
||||
CACHE BOOL "Disabled FetchContent for FMT" FORCE)
|
||||
set(AARE_FETCH_PYBIND11
|
||||
OFF
|
||||
CACHE BOOL "Disabled FetchContent for pybind11" FORCE)
|
||||
set(AARE_FETCH_CATCH
|
||||
OFF
|
||||
CACHE BOOL "Disabled FetchContent for catch2" FORCE)
|
||||
set(AARE_FETCH_JSON
|
||||
OFF
|
||||
CACHE BOOL "Disabled FetchContent for nlohmann::json" FORCE)
|
||||
set(AARE_FETCH_ZMQ
|
||||
OFF
|
||||
CACHE BOOL "Disabled FetchContent for libzmq" FORCE)
|
||||
# Still fetch lmfit and Minuit2 when setting AARE_SYSTEM_LIBRARIES since these
|
||||
# are not available on conda-forge
|
||||
endif()
|
||||
|
||||
if(AARE_CUDA)
|
||||
enable_language(CUDA)
|
||||
find_package(CUDAToolkit REQUIRED)
|
||||
|
||||
set(CMAKE_CUDA_STANDARD 17)
|
||||
set(CMAKE_CUDA_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CUDA_EXTENSIONS OFF)
|
||||
set(CMAKE_CUDA_SEPARABLE_COMPILATION ON)
|
||||
|
||||
if(NOT CMAKE_CUDA_ARCHITECTURES)
|
||||
set(CMAKE_CUDA_ARCHITECTURES ${AARE_CUDA_ARCHITECTURES})
|
||||
endif()
|
||||
|
||||
message(STATUS "AARE: CUDA support ENABLED (archs=${CMAKE_CUDA_ARCHITECTURES}, "
|
||||
"toolkit=${CUDAToolkit_VERSION})")
|
||||
else()
|
||||
message(STATUS "AARE: CUDA support DISABLED (CPU-only build)")
|
||||
endif()
|
||||
|
||||
if(AARE_CUDA)
|
||||
@@ -103,158 +131,184 @@ else()
|
||||
endif()
|
||||
|
||||
if(AARE_BENCHMARKS)
|
||||
add_subdirectory(benchmarks)
|
||||
add_subdirectory(benchmarks)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
if(AARE_FETCH_LMFIT)
|
||||
#TODO! Should we fetch lmfit from the web or inlcude a tar.gz in the repo?
|
||||
set(LMFIT_PATCH_COMMAND git apply ${CMAKE_CURRENT_SOURCE_DIR}/patches/lmfit.patch)
|
||||
# TODO! Should we fetch lmfit from the web or inlcude a tar.gz in the repo?
|
||||
set(LMFIT_PATCH_COMMAND git apply
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/patches/lmfit.patch)
|
||||
|
||||
# For cmake < 3.28 we can't supply EXCLUDE_FROM_ALL to FetchContent_Declare
|
||||
# so we need this workaround
|
||||
if (${CMAKE_VERSION} VERSION_LESS "3.28")
|
||||
FetchContent_Declare(
|
||||
lmfit
|
||||
GIT_REPOSITORY https://jugit.fz-juelich.de/mlz/lmfit.git
|
||||
GIT_TAG main
|
||||
PATCH_COMMAND ${LMFIT_PATCH_COMMAND}
|
||||
UPDATE_DISCONNECTED 1
|
||||
)
|
||||
else()
|
||||
FetchContent_Declare(
|
||||
lmfit
|
||||
GIT_REPOSITORY https://jugit.fz-juelich.de/mlz/lmfit.git
|
||||
GIT_TAG main
|
||||
PATCH_COMMAND ${LMFIT_PATCH_COMMAND}
|
||||
UPDATE_DISCONNECTED 1
|
||||
EXCLUDE_FROM_ALL 1
|
||||
)
|
||||
# For cmake < 3.28 we can't supply EXCLUDE_FROM_ALL to FetchContent_Declare so
|
||||
# we need this workaround
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.28")
|
||||
FetchContent_Declare(
|
||||
lmfit
|
||||
GIT_REPOSITORY https://jugit.fz-juelich.de/mlz/lmfit.git
|
||||
GIT_TAG main
|
||||
PATCH_COMMAND ${LMFIT_PATCH_COMMAND}
|
||||
UPDATE_DISCONNECTED 1)
|
||||
else()
|
||||
FetchContent_Declare(
|
||||
lmfit
|
||||
GIT_REPOSITORY https://jugit.fz-juelich.de/mlz/lmfit.git
|
||||
GIT_TAG main
|
||||
PATCH_COMMAND ${LMFIT_PATCH_COMMAND}
|
||||
UPDATE_DISCONNECTED 1
|
||||
EXCLUDE_FROM_ALL 1)
|
||||
endif()
|
||||
|
||||
# Disable what we don't need from lmfit
|
||||
set(BUILD_TESTING
|
||||
OFF
|
||||
CACHE BOOL "")
|
||||
set(LMFIT_CPPTEST
|
||||
OFF
|
||||
CACHE BOOL "")
|
||||
set(LIB_MAN
|
||||
OFF
|
||||
CACHE BOOL "")
|
||||
set(LMFIT_CPPTEST
|
||||
OFF
|
||||
CACHE BOOL "")
|
||||
set(BUILD_SHARED_LIBS
|
||||
OFF
|
||||
CACHE BOOL "")
|
||||
|
||||
if(${CMAKE_VERSION} VERSION_LESS "3.28")
|
||||
if(NOT lmfit_POPULATED)
|
||||
FetchContent_Populate(lmfit)
|
||||
add_subdirectory(${lmfit_SOURCE_DIR} ${lmfit_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
|
||||
else()
|
||||
FetchContent_MakeAvailable(lmfit)
|
||||
endif()
|
||||
|
||||
#Disable what we don't need from lmfit
|
||||
set(BUILD_TESTING OFF CACHE BOOL "")
|
||||
set(LMFIT_CPPTEST OFF CACHE BOOL "")
|
||||
set(LIB_MAN OFF CACHE BOOL "")
|
||||
set(LMFIT_CPPTEST OFF CACHE BOOL "")
|
||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL "")
|
||||
|
||||
if (${CMAKE_VERSION} VERSION_LESS "3.28")
|
||||
if(NOT lmfit_POPULATED)
|
||||
FetchContent_Populate(lmfit)
|
||||
add_subdirectory(${lmfit_SOURCE_DIR} ${lmfit_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
else()
|
||||
FetchContent_MakeAvailable(lmfit)
|
||||
endif()
|
||||
|
||||
set_property(TARGET lmfit PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET lmfit PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
else()
|
||||
find_package(lmfit REQUIRED)
|
||||
find_package(lmfit REQUIRED)
|
||||
endif()
|
||||
|
||||
|
||||
if(AARE_FETCH_MINUIT2)
|
||||
FetchContent_Declare(
|
||||
Minuit2
|
||||
GIT_REPOSITORY https://github.com/GooFit/Minuit2.git
|
||||
GIT_TAG master
|
||||
)
|
||||
# Disable Minuit2 extras we don't need
|
||||
set(minuit2_mpi OFF CACHE BOOL "")
|
||||
set(minuit2_omp OFF CACHE BOOL "")
|
||||
set(BUILD_TESTING OFF CACHE BOOL "")
|
||||
set(CMAKE_POLICY_VERSION_MINIMUM 3.5 CACHE STRING "Allow older CMake compat for Minuit2")
|
||||
FetchContent_MakeAvailable(Minuit2)
|
||||
unset(CMAKE_POLICY_VERSION_MINIMUM CACHE)
|
||||
set_property(TARGET Minuit2Math PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET Minuit2 PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
# Patch minuit2 to avoid messing with cmake policies
|
||||
set(MINUIT2_PATCH_COMMAND git apply
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/patches/minuit2.patch)
|
||||
FetchContent_Declare(
|
||||
Minuit2
|
||||
GIT_REPOSITORY https://github.com/GooFit/Minuit2.git
|
||||
GIT_TAG master
|
||||
PATCH_COMMAND ${MINUIT2_PATCH_COMMAND}
|
||||
UPDATE_DISCONNECTED 1)
|
||||
# Disable Minuit2 extras we don't need
|
||||
set(minuit2_mpi
|
||||
OFF
|
||||
CACHE BOOL "")
|
||||
set(minuit2_omp
|
||||
OFF
|
||||
CACHE BOOL "")
|
||||
set(BUILD_TESTING
|
||||
OFF
|
||||
CACHE BOOL "")
|
||||
FetchContent_MakeAvailable(Minuit2)
|
||||
set_property(TARGET Minuit2Math PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET Minuit2 PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
else()
|
||||
find_package(Minuit2 REQUIRED)
|
||||
find_package(Minuit2 REQUIRED)
|
||||
endif()
|
||||
|
||||
|
||||
if(AARE_FETCH_ZMQ)
|
||||
# Fetchcontent_Declare is deprecated need to find a way to update this
|
||||
# for now setting the policy to old is enough
|
||||
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.30")
|
||||
cmake_policy(SET CMP0169 OLD)
|
||||
endif()
|
||||
set(ZMQ_PATCH_COMMAND git apply ${CMAKE_CURRENT_SOURCE_DIR}/patches/libzmq_cmake_version.patch)
|
||||
FetchContent_Declare(
|
||||
libzmq
|
||||
GIT_REPOSITORY https://github.com/zeromq/libzmq.git
|
||||
GIT_TAG v4.3.4
|
||||
PATCH_COMMAND ${ZMQ_PATCH_COMMAND}
|
||||
UPDATE_DISCONNECTED 1
|
||||
)
|
||||
# Disable unwanted options from libzmq
|
||||
set(BUILD_TESTS OFF CACHE BOOL "Switch off libzmq test build")
|
||||
set(BUILD_SHARED OFF CACHE BOOL "Switch off libzmq shared libs")
|
||||
set(WITH_PERF_TOOL OFF CACHE BOOL "")
|
||||
set(ENABLE_CPACK OFF CACHE BOOL "")
|
||||
set(ENABLE_CLANG OFF CACHE BOOL "")
|
||||
set(ENABLE_CURVE OFF CACHE BOOL "")
|
||||
set(ENABLE_DRAFTS OFF CACHE BOOL "")
|
||||
# Fetchcontent_Declare is deprecated need to find a way to update this for now
|
||||
# setting the policy to old is enough
|
||||
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.30")
|
||||
cmake_policy(SET CMP0169 OLD)
|
||||
endif()
|
||||
set(ZMQ_PATCH_COMMAND
|
||||
git apply ${CMAKE_CURRENT_SOURCE_DIR}/patches/libzmq_cmake_version.patch)
|
||||
FetchContent_Declare(
|
||||
libzmq
|
||||
GIT_REPOSITORY https://github.com/zeromq/libzmq.git
|
||||
GIT_TAG v4.3.4
|
||||
PATCH_COMMAND ${ZMQ_PATCH_COMMAND}
|
||||
UPDATE_DISCONNECTED 1)
|
||||
# Disable unwanted options from libzmq
|
||||
set(BUILD_TESTS
|
||||
OFF
|
||||
CACHE BOOL "Switch off libzmq test build")
|
||||
set(BUILD_SHARED
|
||||
OFF
|
||||
CACHE BOOL "Switch off libzmq shared libs")
|
||||
set(WITH_PERF_TOOL
|
||||
OFF
|
||||
CACHE BOOL "")
|
||||
set(ENABLE_CPACK
|
||||
OFF
|
||||
CACHE BOOL "")
|
||||
set(ENABLE_CLANG
|
||||
OFF
|
||||
CACHE BOOL "")
|
||||
set(ENABLE_CURVE
|
||||
OFF
|
||||
CACHE BOOL "")
|
||||
set(ENABLE_DRAFTS
|
||||
OFF
|
||||
CACHE BOOL "")
|
||||
|
||||
# TODO! Verify that this is what we want to do in aare
|
||||
# Using GetProperties and Populate to be able to exclude zmq
|
||||
# from install (not possible with FetchContent_MakeAvailable(libzmq))
|
||||
FetchContent_GetProperties(libzmq)
|
||||
if(NOT libzmq_POPULATED)
|
||||
FetchContent_Populate(libzmq)
|
||||
add_subdirectory(${libzmq_SOURCE_DIR} ${libzmq_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
# TODO! Verify that this is what we want to do in aare Using GetProperties and
|
||||
# Populate to be able to exclude zmq from install (not possible with
|
||||
# FetchContent_MakeAvailable(libzmq))
|
||||
FetchContent_GetProperties(libzmq)
|
||||
if(NOT libzmq_POPULATED)
|
||||
FetchContent_Populate(libzmq)
|
||||
add_subdirectory(${libzmq_SOURCE_DIR} ${libzmq_BINARY_DIR} EXCLUDE_FROM_ALL)
|
||||
endif()
|
||||
else()
|
||||
find_package(ZeroMQ 4 REQUIRED)
|
||||
find_package(ZeroMQ 4 REQUIRED)
|
||||
endif()
|
||||
|
||||
|
||||
if (AARE_FETCH_FMT)
|
||||
set(FMT_TEST OFF CACHE INTERNAL "disabling fmt tests")
|
||||
FetchContent_Declare(
|
||||
fmt
|
||||
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
|
||||
GIT_TAG 10.2.1
|
||||
GIT_PROGRESS TRUE
|
||||
USES_TERMINAL_DOWNLOAD TRUE
|
||||
)
|
||||
set(FMT_INSTALL ON CACHE BOOL "")
|
||||
# set(FMT_CMAKE_DIR "")
|
||||
FetchContent_MakeAvailable(fmt)
|
||||
set_property(TARGET fmt PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
install(TARGETS fmt
|
||||
EXPORT ${project}-targets
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
)
|
||||
if(AARE_FETCH_FMT)
|
||||
set(FMT_TEST
|
||||
OFF
|
||||
CACHE INTERNAL "disabling fmt tests")
|
||||
FetchContent_Declare(
|
||||
fmt
|
||||
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
|
||||
GIT_TAG 12.1.0
|
||||
GIT_PROGRESS TRUE
|
||||
USES_TERMINAL_DOWNLOAD TRUE)
|
||||
set(FMT_INSTALL
|
||||
ON
|
||||
CACHE BOOL "")
|
||||
# set(FMT_CMAKE_DIR "")
|
||||
FetchContent_MakeAvailable(fmt)
|
||||
set_property(TARGET fmt PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
install(
|
||||
TARGETS fmt
|
||||
EXPORT ${project}-targets
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
INCLUDES
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
else()
|
||||
find_package(fmt 6 REQUIRED)
|
||||
find_package(fmt 6 REQUIRED)
|
||||
endif()
|
||||
|
||||
if(AARE_FETCH_JSON)
|
||||
FetchContent_Declare(
|
||||
json
|
||||
URL https://github.com/nlohmann/json/releases/download/v3.11.3/json.tar.xz)
|
||||
set(JSON_Install
|
||||
ON
|
||||
CACHE BOOL "")
|
||||
FetchContent_MakeAvailable(json)
|
||||
set(NLOHMANN_JSON_TARGET_NAME nlohmann_json)
|
||||
|
||||
if (AARE_FETCH_JSON)
|
||||
FetchContent_Declare(
|
||||
json
|
||||
URL https://github.com/nlohmann/json/releases/download/v3.11.3/json.tar.xz
|
||||
)
|
||||
set(JSON_Install ON CACHE BOOL "")
|
||||
FetchContent_MakeAvailable(json)
|
||||
set(NLOHMANN_JSON_TARGET_NAME nlohmann_json)
|
||||
|
||||
install(
|
||||
TARGETS nlohmann_json
|
||||
EXPORT "${TARGETS_EXPORT_NAME}"
|
||||
)
|
||||
message(STATUS "target: ${NLOHMANN_JSON_TARGET_NAME}")
|
||||
install(TARGETS nlohmann_json EXPORT "${TARGETS_EXPORT_NAME}")
|
||||
message(STATUS "target: ${NLOHMANN_JSON_TARGET_NAME}")
|
||||
else()
|
||||
find_package(nlohmann_json 3.11.3 REQUIRED)
|
||||
find_package(nlohmann_json 3.11.3 REQUIRED)
|
||||
endif()
|
||||
|
||||
include(GNUInstallDirs)
|
||||
@@ -268,7 +322,6 @@ endif()
|
||||
string(TOUPPER "${PROJECT_NAME}" PROJECT_NAME_UPPER)
|
||||
string(TOLOWER "${PROJECT_NAME}" PROJECT_NAME_LOWER)
|
||||
|
||||
|
||||
# Set targets export name (used by slsDetectorPackage and dependencies)
|
||||
set(TARGETS_EXPORT_NAME "${PROJECT_NAME_LOWER}-targets")
|
||||
set(namespace "aare::")
|
||||
@@ -277,57 +330,41 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||
|
||||
# Check if project is being used directly or via add_subdirectory
|
||||
set(AARE_MASTER_PROJECT OFF)
|
||||
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
set(AARE_MASTER_PROJECT ON)
|
||||
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
set(AARE_MASTER_PROJECT ON)
|
||||
endif()
|
||||
|
||||
add_library(aare_compiler_flags INTERFACE)
|
||||
target_compile_features(aare_compiler_flags INTERFACE cxx_std_17)
|
||||
|
||||
|
||||
|
||||
#################
|
||||
# ##############################################################################
|
||||
# MSVC specific #
|
||||
#################
|
||||
# ##############################################################################
|
||||
if(MSVC)
|
||||
add_compile_definitions(AARE_MSVC)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
add_compile_definitions(AARE_MSVC)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
message(STATUS "Release build")
|
||||
target_compile_options(aare_compiler_flags INTERFACE /O2)
|
||||
else()
|
||||
else()
|
||||
message(STATUS "Debug build")
|
||||
target_compile_options(
|
||||
aare_compiler_flags
|
||||
INTERFACE
|
||||
/Od
|
||||
/Zi
|
||||
/MDd
|
||||
/D_ITERATOR_DEBUG_LEVEL=2
|
||||
)
|
||||
target_link_options(
|
||||
aare_compiler_flags
|
||||
INTERFACE
|
||||
/DEBUG:FULL
|
||||
)
|
||||
endif()
|
||||
target_compile_options(
|
||||
aare_compiler_flags
|
||||
INTERFACE
|
||||
/w # disable warnings
|
||||
)
|
||||
|
||||
target_compile_options(aare_compiler_flags
|
||||
INTERFACE /Od /Zi /MDd /D_ITERATOR_DEBUG_LEVEL=2)
|
||||
target_link_options(aare_compiler_flags INTERFACE /DEBUG:FULL)
|
||||
endif()
|
||||
target_compile_options(aare_compiler_flags INTERFACE /w # disable warnings
|
||||
)
|
||||
|
||||
else()
|
||||
######################
|
||||
# GCC/Clang specific #
|
||||
######################
|
||||
# ############################################################################
|
||||
# GCC/Clang specific #
|
||||
# ############################################################################
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
message(STATUS "Release build")
|
||||
target_compile_options(aare_compiler_flags INTERFACE -O3)
|
||||
else()
|
||||
else()
|
||||
message(STATUS "Debug build")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Common flags for GCC and Clang
|
||||
# The strict host warnings (especially -Wold-style-cast and -Wdouble-promotion)
|
||||
@@ -350,36 +387,31 @@ target_compile_options(
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-Werror=return-type> #important can cause segfault in optimzed builds
|
||||
)
|
||||
|
||||
endif() #GCC/Clang specific
|
||||
endif() # GCC/Clang specific
|
||||
|
||||
if(AARE_PYTHON_BINDINGS)
|
||||
add_subdirectory(python)
|
||||
add_subdirectory(python)
|
||||
endif()
|
||||
|
||||
if(AARE_ASAN)
|
||||
message(STATUS "AddressSanitizer enabled")
|
||||
target_compile_options(
|
||||
aare_compiler_flags
|
||||
INTERFACE
|
||||
-fsanitize=address,undefined,pointer-compare
|
||||
-fno-omit-frame-pointer
|
||||
)
|
||||
target_link_libraries(
|
||||
aare_compiler_flags
|
||||
INTERFACE
|
||||
-fsanitize=address,undefined,pointer-compare
|
||||
-fno-omit-frame-pointer
|
||||
)
|
||||
message(STATUS "AddressSanitizer enabled")
|
||||
target_compile_options(
|
||||
aare_compiler_flags INTERFACE -fsanitize=address,undefined,pointer-compare
|
||||
-fno-omit-frame-pointer)
|
||||
target_link_libraries(
|
||||
aare_compiler_flags INTERFACE -fsanitize=address,undefined,pointer-compare
|
||||
-fno-omit-frame-pointer)
|
||||
endif()
|
||||
|
||||
if(AARE_TESTS)
|
||||
enable_testing()
|
||||
add_subdirectory(tests)
|
||||
target_compile_definitions(tests PRIVATE AARE_TESTS)
|
||||
enable_testing()
|
||||
add_subdirectory(tests)
|
||||
target_compile_definitions(tests PRIVATE AARE_TESTS)
|
||||
endif()
|
||||
|
||||
###------------------------------------------------------------------------------MAIN LIBRARY
|
||||
###------------------------------------------------------------------------------------------
|
||||
# ------------------------------------------------------------------------------MAIN
|
||||
# LIBRARY
|
||||
# ------------------------------------------------------------------------------------------
|
||||
|
||||
set(PUBLICHEADERS
|
||||
include/aare/ArrayExpr.hpp
|
||||
@@ -449,55 +481,46 @@ set(SourceFiles
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RawSubFile.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/to_string.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/utils/task.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/utils/ifstream_helpers.cpp
|
||||
)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/utils/ifstream_helpers.cpp)
|
||||
|
||||
add_library(aare_core STATIC ${SourceFiles})
|
||||
target_include_directories(aare_core PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||
)
|
||||
target_include_directories(
|
||||
aare_core PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
|
||||
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
target_link_libraries(
|
||||
aare_core
|
||||
PUBLIC
|
||||
fmt::fmt
|
||||
nlohmann_json::nlohmann_json
|
||||
${STD_FS_LIB} # from helpers.cmake
|
||||
Minuit2::Minuit2
|
||||
PRIVATE
|
||||
aare_compiler_flags
|
||||
Threads::Threads
|
||||
$<BUILD_INTERFACE:lmfit>
|
||||
)
|
||||
aare_core
|
||||
PUBLIC fmt::fmt nlohmann_json::nlohmann_json ${STD_FS_LIB} # from
|
||||
# helpers.cmake
|
||||
Minuit2::Minuit2
|
||||
PRIVATE aare_compiler_flags Threads::Threads $<BUILD_INTERFACE:lmfit>)
|
||||
|
||||
target_include_directories(aare_core SYSTEM PRIVATE
|
||||
$<TARGET_PROPERTY:Minuit2::Minuit2,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
target_include_directories(
|
||||
aare_core SYSTEM
|
||||
PRIVATE $<TARGET_PROPERTY:Minuit2::Minuit2,INTERFACE_INCLUDE_DIRECTORIES>)
|
||||
|
||||
set_property(TARGET aare_core PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
if(AARE_TESTS)
|
||||
target_compile_definitions(aare_core PRIVATE AARE_TESTS)
|
||||
target_compile_definitions(aare_core PRIVATE AARE_TESTS)
|
||||
endif()
|
||||
if(AARE_VERBOSE)
|
||||
target_compile_definitions(aare_core PUBLIC AARE_VERBOSE)
|
||||
target_compile_definitions(aare_core PUBLIC AARE_LOG_LEVEL=aare::logDEBUG5)
|
||||
target_compile_definitions(aare_core PUBLIC AARE_VERBOSE)
|
||||
target_compile_definitions(aare_core PUBLIC AARE_LOG_LEVEL=aare::logDEBUG5)
|
||||
else()
|
||||
target_compile_definitions(aare_core PUBLIC AARE_LOG_LEVEL=aare::logERROR)
|
||||
target_compile_definitions(aare_core PUBLIC AARE_LOG_LEVEL=aare::logERROR)
|
||||
endif()
|
||||
|
||||
if(AARE_CUSTOM_ASSERT)
|
||||
target_compile_definitions(aare_core PUBLIC AARE_CUSTOM_ASSERT)
|
||||
target_compile_definitions(aare_core PUBLIC AARE_CUSTOM_ASSERT)
|
||||
endif()
|
||||
|
||||
set_target_properties(aare_core PROPERTIES
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
PUBLIC_HEADER "${PUBLICHEADERS}"
|
||||
)
|
||||
set_target_properties(
|
||||
aare_core PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
PUBLIC_HEADER "${PUBLICHEADERS}")
|
||||
|
||||
if(AARE_CUDA)
|
||||
add_library(aare_cuda INTERFACE)
|
||||
@@ -516,38 +539,35 @@ if(AARE_CUDA)
|
||||
endif()
|
||||
|
||||
if(AARE_TESTS)
|
||||
set(TestSources
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/algorithm.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/calibration.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/defs.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/decode.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Dtype.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Frame.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/DetectorGeometry.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Interpolation.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RawMasterFile.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/NDArray.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/NDView.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/ClusterFinder.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/ClusterVector.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Cluster.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/CalculateEta.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/ClusterFile.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/ClusterFinderMT.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Pedestal.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/JungfrauDataFile.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/NumpyFile.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/NumpyHelpers.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RawFile.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RawSubFile.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/utils/task.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/to_string.test.cpp
|
||||
|
||||
)
|
||||
target_sources(tests PRIVATE ${TestSources} )
|
||||
set(TestSources
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/algorithm.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/calibration.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/defs.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/decode.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Dtype.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Frame.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/DetectorGeometry.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Interpolation.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RawMasterFile.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/NDArray.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/NDView.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/ClusterFinder.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/ClusterVector.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Cluster.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/CalculateEta.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/ClusterFile.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/ClusterFinderMT.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Pedestal.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/JungfrauDataFile.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/NumpyFile.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/NumpyHelpers.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RawFile.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/RawSubFile.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/utils/task.test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/to_string.test.cpp)
|
||||
target_sources(tests PRIVATE ${TestSources})
|
||||
endif()
|
||||
|
||||
|
||||
if(AARE_MASTER_PROJECT)
|
||||
set(AARE_INSTALL_TARGETS aare_core aare_compiler_flags)
|
||||
if(AARE_CUDA)
|
||||
@@ -564,54 +584,64 @@ endif()
|
||||
set(CMAKE_INSTALL_RPATH $ORIGIN)
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
|
||||
|
||||
|
||||
# #Overall target to link to when using the library
|
||||
# add_library(aare INTERFACE)
|
||||
# #Overall target to link to when using the library add_library(aare INTERFACE)
|
||||
# target_link_libraries(aare INTERFACE aare_core aare_compiler_flags)
|
||||
# target_include_directories(aare INTERFACE
|
||||
# $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
# $<INSTALL_INTERFACE:include>
|
||||
# )
|
||||
# target_include_directories(aare INTERFACE
|
||||
# $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
# $<INSTALL_INTERFACE:include> )
|
||||
|
||||
# add_subdirectory(examples)
|
||||
|
||||
if(AARE_DOCS)
|
||||
add_subdirectory(docs)
|
||||
add_subdirectory(docs)
|
||||
endif()
|
||||
|
||||
|
||||
# custom target to run check formatting with clang-format
|
||||
add_custom_target(
|
||||
check-format
|
||||
COMMAND find \( -name "*.cpp" -o -name "*.hpp" \) -not -path "./build/*" | xargs -I {} -n 1 -P 10 bash -c "clang-format -Werror -style=\"file:.clang-format\" {} | diff {} -"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT "Checking code formatting with clang-format"
|
||||
VERBATIM
|
||||
|
||||
)
|
||||
check-format
|
||||
COMMAND
|
||||
find \\ (-name "*.cpp" -o -name "*.hpp" \\) -not -path "./build/*" | xargs
|
||||
-I {} -n 1 -P 10 bash -c
|
||||
"clang-format -Werror -style=\"file:.clang-format\" {} | diff {} -"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT "Checking code formatting with clang-format"
|
||||
VERBATIM)
|
||||
|
||||
add_custom_target(
|
||||
format-files
|
||||
COMMAND find \( -name "*.cpp" -o -name "*.hpp" \) -not -path "./build/*" | xargs -I {} -n 1 -P 10 bash -c "clang-format -i -style=\"file:.clang-format\" {}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT "Formatting with clang-format"
|
||||
VERBATIM
|
||||
)
|
||||
format-files
|
||||
COMMAND
|
||||
find \\ (-name "*.cpp" -o -name "*.hpp" \\) -not -path "./build/*" | xargs
|
||||
-I {} -n 1 -P 10 bash -c "clang-format -i -style=\"file:.clang-format\" {}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT "Formatting with clang-format"
|
||||
VERBATIM)
|
||||
|
||||
if (AARE_IN_GITHUB_ACTIONS)
|
||||
message(STATUS "Running in Github Actions")
|
||||
set(CLANG_TIDY_COMMAND "clang-tidy-17")
|
||||
if(AARE_IN_GITHUB_ACTIONS)
|
||||
message(STATUS "Running in Github Actions")
|
||||
set(CLANG_TIDY_COMMAND "clang-tidy-17")
|
||||
else()
|
||||
set(CLANG_TIDY_COMMAND "clang-tidy")
|
||||
set(CLANG_TIDY_COMMAND "clang-tidy")
|
||||
endif()
|
||||
|
||||
add_custom_target(
|
||||
clang-tidy
|
||||
COMMAND find \( -path "./src/*" -a -not -path "./src/python/*" -a \( -name "*.cpp" -not -name "*.test.cpp" \) \) -not -name "CircularFifo.hpp" -not -name "ProducerConsumerQueue.hpp" -not -name "VariableSizeClusterFinder.hpp" | xargs -I {} -n 1 -P 10 bash -c "${CLANG_TIDY_COMMAND} --config-file=.clang-tidy -p build {}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT "linting with clang-tidy"
|
||||
VERBATIM
|
||||
)
|
||||
clang-tidy
|
||||
COMMAND
|
||||
find \\ (-path
|
||||
"./src/*"
|
||||
-a
|
||||
-not
|
||||
-path
|
||||
"./src/python/*"
|
||||
-a
|
||||
\\
|
||||
(-name "*.cpp" -not -name "*.test.cpp" \\)
|
||||
\\) -not -name "CircularFifo.hpp" -not -name
|
||||
"ProducerConsumerQueue.hpp" -not -name "VariableSizeClusterFinder.hpp" |
|
||||
xargs -I {} -n 1 -P 10 bash -c
|
||||
"${CLANG_TIDY_COMMAND} --config-file=.clang-tidy -p build {}"
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
COMMENT "linting with clang-tidy"
|
||||
VERBATIM)
|
||||
|
||||
if(AARE_MASTER_PROJECT)
|
||||
set(CMAKE_INSTALL_DIR "share/cmake/${PROJECT_NAME}")
|
||||
|
||||
@@ -79,4 +79,15 @@ make install
|
||||
|
||||
```bash
|
||||
conda build . --variants="{python: [3.11, 3.12, 3.13]}"
|
||||
```
|
||||
```
|
||||
|
||||
## Developer's guide
|
||||
|
||||
We are looking forward to your contributions via pull requests!
|
||||
|
||||
If you want to fix an existing bug or propose a new feature:
|
||||
|
||||
1. Install `pre-commit` python package and setup it `pre-commit install`
|
||||
2. Create a new branch with `git branch branch_name`
|
||||
3. Implement your changes and make a commit (`pre-commit` will check your code automatically)
|
||||
4. Push your commit and open a pull request if needed
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
- Added a new Minuit2-based fitting framework for ``Gaussian``, ``RisingScurve``, ``FallingScurve``, ``Pol1`` and ``Pol2`` models.
|
||||
- setter and getter for nSigma for ClusterFinder ``aare.ClusterFinder().nSigma = 2``, ``aare.ClusterFinderMT().set_nSigma(2)``
|
||||
- mask opeartor for ClusterVector ``masked_clustervector = aare.ClusterVector()(mask)``
|
||||
|
||||
### Bugfixes:
|
||||
|
||||
|
||||
+21
-16
@@ -2,34 +2,39 @@
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
|
||||
FetchContent_Declare(
|
||||
benchmark
|
||||
GIT_REPOSITORY https://github.com/google/benchmark.git
|
||||
GIT_TAG v1.8.3 # Change to the latest version if needed
|
||||
benchmark
|
||||
GIT_REPOSITORY https://github.com/google/benchmark.git
|
||||
GIT_TAG v1.8.3 # Change to the latest version if needed
|
||||
)
|
||||
|
||||
# Ensure Google Benchmark is built correctly
|
||||
set(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL "" FORCE)
|
||||
set(BENCHMARK_ENABLE_TESTING
|
||||
OFF
|
||||
CACHE BOOL "" FORCE)
|
||||
|
||||
FetchContent_MakeAvailable(benchmark)
|
||||
|
||||
add_executable(benchmarks)
|
||||
|
||||
target_sources(benchmarks PRIVATE ndarray_benchmark.cpp calculateeta_benchmark.cpp reduce_benchmark.cpp)
|
||||
target_sources(
|
||||
benchmarks PRIVATE ndarray_benchmark.cpp calculateeta_benchmark.cpp
|
||||
reduce_benchmark.cpp)
|
||||
|
||||
# Link Google Benchmark and other necessary libraries
|
||||
target_link_libraries(benchmarks PRIVATE benchmark::benchmark aare_core aare_compiler_flags)
|
||||
target_link_libraries(benchmarks PRIVATE benchmark::benchmark aare_core
|
||||
aare_compiler_flags)
|
||||
|
||||
# Set output properties
|
||||
set_target_properties(benchmarks PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
OUTPUT_NAME run_benchmarks
|
||||
)
|
||||
set_target_properties(
|
||||
benchmarks PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
OUTPUT_NAME run_benchmarks)
|
||||
|
||||
add_executable(fit_benchmark fit_benchmark.cpp)
|
||||
target_link_libraries(fit_benchmark PRIVATE benchmark::benchmark aare_core aare_compiler_flags)
|
||||
target_include_directories(fit_benchmark SYSTEM PRIVATE
|
||||
$<TARGET_PROPERTY:Minuit2::Minuit2,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
set_target_properties(fit_benchmark PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
target_link_libraries(fit_benchmark PRIVATE benchmark::benchmark aare_core
|
||||
aare_compiler_flags)
|
||||
target_include_directories(
|
||||
fit_benchmark SYSTEM
|
||||
PRIVATE $<TARGET_PROPERTY:Minuit2::Minuit2,INTERFACE_INCLUDE_DIRECTORIES>)
|
||||
set_target_properties(fit_benchmark PROPERTIES RUNTIME_OUTPUT_DIRECTORY
|
||||
${CMAKE_BINARY_DIR})
|
||||
@@ -1,8 +1,8 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
#include "aare/Fit.hpp"
|
||||
#include "aare/Chi2.hpp"
|
||||
#include "aare/Models.hpp"
|
||||
#include "aare/Fit.hpp"
|
||||
#include "aare/FitModel.hpp"
|
||||
#include "aare/Models.hpp"
|
||||
|
||||
#include <benchmark/benchmark.h>
|
||||
#include <cmath>
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
struct TestCase {
|
||||
std::string name;
|
||||
double true_A;
|
||||
@@ -21,12 +20,12 @@ struct TestCase {
|
||||
|
||||
static const std::vector<TestCase> &get_test_cases() {
|
||||
static const std::vector<TestCase> cases = {
|
||||
{"Clean_signal", 1000.0, 50.0, 5.0, 0.02},
|
||||
{"Moderate_noise", 1000.0, 50.0, 5.0, 0.10},
|
||||
{"High_noise", 1000.0, 50.0, 5.0, 0.30},
|
||||
{"Narrow_peak", 500.0, 25.0, 1.0, 0.05},
|
||||
{"Wide_peak", 200.0, 100.0, 20.0, 0.05},
|
||||
{"Off_center_peak", 800.0, -15.0, 3.0, 0.05},
|
||||
{"Clean_signal", 1000.0, 50.0, 5.0, 0.02},
|
||||
{"Moderate_noise", 1000.0, 50.0, 5.0, 0.10},
|
||||
{"High_noise", 1000.0, 50.0, 5.0, 0.30},
|
||||
{"Narrow_peak", 500.0, 25.0, 1.0, 0.05},
|
||||
{"Wide_peak", 200.0, 100.0, 20.0, 0.05},
|
||||
{"Off_center_peak", 800.0, -15.0, 3.0, 0.05},
|
||||
};
|
||||
return cases;
|
||||
}
|
||||
@@ -58,21 +57,18 @@ static GeneratedData generate_gaussian_data(const TestCase &tc) {
|
||||
|
||||
for (ssize_t i = 0; i < N_POINTS; ++i) {
|
||||
d.x[i] = x_min + i * dx;
|
||||
double clean = tc.true_A *
|
||||
std::exp(-std::pow(d.x[i] - tc.true_mu, 2) /
|
||||
(2.0 * std::pow(tc.true_sig, 2)));
|
||||
double clean = tc.true_A * std::exp(-std::pow(d.x[i] - tc.true_mu, 2) /
|
||||
(2.0 * std::pow(tc.true_sig, 2)));
|
||||
d.y[i] = clean + noise(rng);
|
||||
d.y_err[i] = noise_sigma;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
static void report_accuracy(benchmark::State &state,
|
||||
const TestCase &tc,
|
||||
static void report_accuracy(benchmark::State &state, const TestCase &tc,
|
||||
const aare::NDArray<double, 1> &result) {
|
||||
state.counters["dA"] = result(0) - tc.true_A;
|
||||
state.counters["dMu"] = result(1) - tc.true_mu;
|
||||
state.counters["dA"] = result(0) - tc.true_A;
|
||||
state.counters["dMu"] = result(1) - tc.true_mu;
|
||||
state.counters["dSig"] = result(2) - tc.true_sig;
|
||||
}
|
||||
|
||||
@@ -104,14 +100,17 @@ static void BM_FitGausMinuitGrad(benchmark::State &state) {
|
||||
auto xv = data.x.view();
|
||||
auto yv = data.y.view();
|
||||
|
||||
const auto model = aare::FitModel<aare::model::Gaussian>(/*strategy = */0,
|
||||
/*max_calls = */500, // increase for noisy signals
|
||||
/*tolerance = */0.5,
|
||||
/*compute_errors = */false);
|
||||
const auto model = aare::FitModel<aare::model::Gaussian>(
|
||||
/*strategy = */ 0,
|
||||
/*max_calls = */ 500, // increase for noisy signals
|
||||
/*tolerance = */ 0.5,
|
||||
/*compute_errors = */ false);
|
||||
|
||||
aare::NDArray<double, 1> result;
|
||||
for (auto _ : state) {
|
||||
result = aare::fit_pixel<aare::model::Gaussian, aare::func::Chi2Gaussian>(model, xv, yv);
|
||||
result =
|
||||
aare::fit_pixel<aare::model::Gaussian, aare::func::Chi2Gaussian>(
|
||||
model, xv, yv);
|
||||
benchmark::DoNotOptimize(result.data());
|
||||
}
|
||||
|
||||
@@ -127,11 +126,15 @@ static void BM_FitGausMinuitGradHesse(benchmark::State &state) {
|
||||
auto yv = data.y.view();
|
||||
auto ev = data.y_err.view();
|
||||
|
||||
const auto model = aare::FitModel<aare::model::Gaussian>(0, 500, 0.5, true); // compute_errors = true -> Runs Hesse and provides errors on fitted params
|
||||
const auto model = aare::FitModel<aare::model::Gaussian>(
|
||||
0, 500, 0.5, true); // compute_errors = true -> Runs Hesse and provides
|
||||
// errors on fitted params
|
||||
|
||||
aare::NDArray<double, 1> result;
|
||||
for (auto _ : state) {
|
||||
result = aare::fit_pixel<aare::model::Gaussian, aare::func::Chi2Gaussian>(model, xv, yv, ev);
|
||||
result =
|
||||
aare::fit_pixel<aare::model::Gaussian, aare::func::Chi2Gaussian>(
|
||||
model, xv, yv, ev);
|
||||
benchmark::DoNotOptimize(result.data());
|
||||
}
|
||||
|
||||
@@ -140,16 +143,14 @@ static void BM_FitGausMinuitGradHesse(benchmark::State &state) {
|
||||
|
||||
// Also report Hesse uncertainties
|
||||
if (result.size() >= 6) {
|
||||
state.counters["errA"] = result(3);
|
||||
state.counters["errMu"] = result(4);
|
||||
state.counters["errA"] = result(3);
|
||||
state.counters["errMu"] = result(4);
|
||||
state.counters["errSig"] = result(5);
|
||||
}
|
||||
state.SetLabel(tc.name);
|
||||
}
|
||||
|
||||
BENCHMARK(BM_FitGausLm)
|
||||
->DenseRange(0, 5)
|
||||
->Unit(benchmark::kMicrosecond);
|
||||
BENCHMARK(BM_FitGausLm)->DenseRange(0, 5)->Unit(benchmark::kMicrosecond);
|
||||
|
||||
BENCHMARK(BM_FitGausMinuitGrad)
|
||||
->DenseRange(0, 5)
|
||||
|
||||
+10
-10
@@ -1,11 +1,11 @@
|
||||
#Look for an executable called sphinx-build
|
||||
find_program(SPHINX_EXECUTABLE
|
||||
NAMES sphinx-build sphinx-build-3.6
|
||||
DOC "Path to sphinx-build executable")
|
||||
|
||||
# Look for an executable called sphinx-build
|
||||
find_program(
|
||||
SPHINX_EXECUTABLE
|
||||
NAMES sphinx-build sphinx-build-3.6
|
||||
DOC "Path to sphinx-build executable")
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
#Handle standard arguments to find_package like REQUIRED and QUIET
|
||||
find_package_handle_standard_args(Sphinx
|
||||
"Failed to find sphinx-build executable"
|
||||
SPHINX_EXECUTABLE)
|
||||
|
||||
# Handle standard arguments to find_package like REQUIRED and QUIET
|
||||
find_package_handle_standard_args(
|
||||
Sphinx "Failed to find sphinx-build executable" SPHINX_EXECUTABLE)
|
||||
+48
-41
@@ -1,46 +1,53 @@
|
||||
function(default_build_type val)
|
||||
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
message(STATUS "No build type selected, default to Release")
|
||||
set(CMAKE_BUILD_TYPE ${val} CACHE STRING "Build type (default ${val})" FORCE)
|
||||
endif()
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
message(STATUS "No build type selected, default to Release")
|
||||
set(CMAKE_BUILD_TYPE
|
||||
${val}
|
||||
CACHE STRING "Build type (default ${val})" FORCE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(set_std_fs_lib)
|
||||
# from pybind11
|
||||
# Check if we need to add -lstdc++fs or -lc++fs or nothing
|
||||
if(DEFINED CMAKE_CXX_STANDARD AND CMAKE_CXX_STANDARD LESS 17)
|
||||
set(STD_FS_NO_LIB_NEEDED TRUE)
|
||||
elseif(MSVC)
|
||||
set(STD_FS_NO_LIB_NEEDED TRUE)
|
||||
else()
|
||||
file(
|
||||
WRITE ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
|
||||
"#include <filesystem>\nint main(int argc, char ** argv) {\n std::filesystem::path p(argv[0]);\n return p.string().length();\n}"
|
||||
)
|
||||
try_compile(
|
||||
STD_FS_NO_LIB_NEEDED ${CMAKE_CURRENT_BINARY_DIR}
|
||||
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
|
||||
COMPILE_DEFINITIONS -std=c++17)
|
||||
try_compile(
|
||||
STD_FS_NEEDS_STDCXXFS ${CMAKE_CURRENT_BINARY_DIR}
|
||||
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
|
||||
COMPILE_DEFINITIONS -std=c++17
|
||||
LINK_LIBRARIES stdc++fs)
|
||||
try_compile(
|
||||
STD_FS_NEEDS_CXXFS ${CMAKE_CURRENT_BINARY_DIR}
|
||||
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
|
||||
COMPILE_DEFINITIONS -std=c++17
|
||||
LINK_LIBRARIES c++fs)
|
||||
endif()
|
||||
# from pybind11 Check if we need to add -lstdc++fs or -lc++fs or nothing
|
||||
if(DEFINED CMAKE_CXX_STANDARD AND CMAKE_CXX_STANDARD LESS 17)
|
||||
set(STD_FS_NO_LIB_NEEDED TRUE)
|
||||
elseif(MSVC)
|
||||
set(STD_FS_NO_LIB_NEEDED TRUE)
|
||||
else()
|
||||
file(
|
||||
WRITE ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
|
||||
"#include <filesystem>\nint main(int argc, char ** argv) {\n std::filesystem::path p(argv[0]);\n return p.string().length();\n}"
|
||||
)
|
||||
try_compile(
|
||||
STD_FS_NO_LIB_NEEDED ${CMAKE_CURRENT_BINARY_DIR}
|
||||
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
|
||||
COMPILE_DEFINITIONS -std=c++17)
|
||||
try_compile(
|
||||
STD_FS_NEEDS_STDCXXFS ${CMAKE_CURRENT_BINARY_DIR}
|
||||
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
|
||||
COMPILE_DEFINITIONS -std=c++17
|
||||
LINK_LIBRARIES stdc++fs)
|
||||
try_compile(
|
||||
STD_FS_NEEDS_CXXFS ${CMAKE_CURRENT_BINARY_DIR}
|
||||
SOURCES ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
|
||||
COMPILE_DEFINITIONS -std=c++17
|
||||
LINK_LIBRARIES c++fs)
|
||||
endif()
|
||||
|
||||
if(${STD_FS_NEEDS_STDCXXFS})
|
||||
set(STD_FS_LIB stdc++fs PARENT_SCOPE)
|
||||
elseif(${STD_FS_NEEDS_CXXFS})
|
||||
set(STD_FS_LIB c++fs PARENT_SCOPE)
|
||||
elseif(${STD_FS_NO_LIB_NEEDED})
|
||||
set(STD_FS_LIB "" PARENT_SCOPE)
|
||||
else()
|
||||
message(WARNING "Unknown C++17 compiler - not passing -lstdc++fs")
|
||||
set(STD_FS_LIB "")
|
||||
endif()
|
||||
endfunction()
|
||||
if(${STD_FS_NEEDS_STDCXXFS})
|
||||
set(STD_FS_LIB
|
||||
stdc++fs
|
||||
PARENT_SCOPE)
|
||||
elseif(${STD_FS_NEEDS_CXXFS})
|
||||
set(STD_FS_LIB
|
||||
c++fs
|
||||
PARENT_SCOPE)
|
||||
elseif(${STD_FS_NO_LIB_NEEDED})
|
||||
set(STD_FS_LIB
|
||||
""
|
||||
PARENT_SCOPE)
|
||||
else()
|
||||
message(WARNING "Unknown C++17 compiler - not passing -lstdc++fs")
|
||||
set(STD_FS_LIB "")
|
||||
endif()
|
||||
endfunction()
|
||||
@@ -15,21 +15,17 @@ configure_package_config_file(
|
||||
write_basic_package_version_file(
|
||||
"${PROJECT_BINARY_DIR}/${PROJECT_NAME_LOWER}-config-version.cmake"
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
COMPATIBILITY SameMajorVersion)
|
||||
|
||||
install(FILES
|
||||
"${PROJECT_BINARY_DIR}/${PROJECT_NAME_LOWER}-config.cmake"
|
||||
"${PROJECT_BINARY_DIR}/${PROJECT_NAME_LOWER}-config-version.cmake"
|
||||
install(
|
||||
FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME_LOWER}-config.cmake"
|
||||
"${PROJECT_BINARY_DIR}/${PROJECT_NAME_LOWER}-config-version.cmake"
|
||||
COMPONENT devel
|
||||
DESTINATION ${CMAKE_INSTALL_DIR}
|
||||
)
|
||||
DESTINATION ${CMAKE_INSTALL_DIR})
|
||||
|
||||
|
||||
if (PROJECT_LIBRARIES OR PROJECT_STATIC_LIBRARIES)
|
||||
if(PROJECT_LIBRARIES OR PROJECT_STATIC_LIBRARIES)
|
||||
install(
|
||||
EXPORT "${TARGETS_EXPORT_NAME}"
|
||||
FILE ${PROJECT_NAME_LOWER}-targets.cmake
|
||||
DESTINATION ${CMAKE_INSTALL_DIR}
|
||||
)
|
||||
endif ()
|
||||
DESTINATION ${CMAKE_INSTALL_DIR})
|
||||
endif()
|
||||
@@ -27,7 +27,7 @@ requirements:
|
||||
- pip
|
||||
- numpy >=2.1
|
||||
- scikit-build-core
|
||||
- pybind11 >=2.13.0
|
||||
- pybind11 >=3.0.3
|
||||
- matplotlib # needed in host to solve the environment for run
|
||||
|
||||
run:
|
||||
|
||||
+22
-34
@@ -2,53 +2,41 @@
|
||||
find_package(Doxygen REQUIRED)
|
||||
find_package(Sphinx REQUIRED)
|
||||
|
||||
#Doxygen
|
||||
# Doxygen
|
||||
set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
|
||||
set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
|
||||
configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
|
||||
|
||||
#Sphinx
|
||||
# Sphinx
|
||||
set(SPHINX_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||
set(SPHINX_BUILD ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
|
||||
file(GLOB_RECURSE SPHINX_SOURCE_FILES
|
||||
CONFIGURE_DEPENDS
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/src"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/*.rst"
|
||||
)
|
||||
file(
|
||||
GLOB_RECURSE SPHINX_SOURCE_FILES CONFIGURE_DEPENDS
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/src"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/*.rst")
|
||||
|
||||
foreach(relpath IN LISTS SPHINX_SOURCE_FILES)
|
||||
set(src "${CMAKE_CURRENT_SOURCE_DIR}/src/${relpath}")
|
||||
set(dst "${SPHINX_BUILD}/src/${relpath}")
|
||||
set(src "${CMAKE_CURRENT_SOURCE_DIR}/src/${relpath}")
|
||||
set(dst "${SPHINX_BUILD}/src/${relpath}")
|
||||
|
||||
message(STATUS "Copying ${src} to ${dst}")
|
||||
configure_file("${src}" "${dst}" COPYONLY)
|
||||
message(STATUS "Copying ${src} to ${dst}")
|
||||
configure_file("${src}" "${dst}" COPYONLY)
|
||||
endforeach()
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in"
|
||||
"${SPHINX_BUILD}/conf.py"
|
||||
@ONLY
|
||||
)
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in"
|
||||
"${SPHINX_BUILD}/conf.py" @ONLY)
|
||||
|
||||
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/figures"
|
||||
DESTINATION "${SPHINX_BUILD}")
|
||||
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/figures" DESTINATION "${SPHINX_BUILD}")
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/static/extra.css"
|
||||
"${SPHINX_BUILD}/static/css/extra.css"
|
||||
@ONLY
|
||||
)
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/static/extra.css"
|
||||
"${SPHINX_BUILD}/static/css/extra.css" @ONLY)
|
||||
|
||||
add_custom_target(
|
||||
docs
|
||||
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
|
||||
COMMAND ${SPHINX_EXECUTABLE} -a -b html
|
||||
-Dbreathe_projects.aare=${CMAKE_CURRENT_BINARY_DIR}/xml
|
||||
-c "${SPHINX_BUILD}"
|
||||
${SPHINX_BUILD}/src
|
||||
${SPHINX_BUILD}/html
|
||||
COMMENT "Generating documentation with Sphinx"
|
||||
)
|
||||
|
||||
docs
|
||||
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
|
||||
COMMAND
|
||||
${SPHINX_EXECUTABLE} -a -b html
|
||||
-Dbreathe_projects.aare=${CMAKE_CURRENT_BINARY_DIR}/xml -c "${SPHINX_BUILD}"
|
||||
${SPHINX_BUILD}/src ${SPHINX_BUILD}/html
|
||||
COMMENT "Generating documentation with Sphinx")
|
||||
@@ -70,7 +70,7 @@ Supported are the following :math:`\eta`-functions:
|
||||
The :math:`\eta` values can range between 0,1. Note they only range between 0,1 because the position of the center pixel (red) can change.
|
||||
If the center pixel is in the bottom left pixel :math:`\eta_x` will be close to zero. If the center pixel is in the bottom right pixel :math:`\eta_y` will be close to 1.
|
||||
|
||||
One can apply this :math:`\eta` not only on 2x2 clusters but on clusters with any size. Then the 2x2 subcluster with maximum energy is choosen and the :math:`\eta` function applied on the subcluster.
|
||||
One can apply this :math:`\eta` not only on 2x2 clusters but on clusters with any size. Then the 2x2 subcluster with maximum energy is chosen and the :math:`\eta` function applied on the subcluster.
|
||||
|
||||
.. doxygenfunction:: aare::calculate_eta2(const ClusterVector<ClusterType>&)
|
||||
|
||||
@@ -150,7 +150,7 @@ Interpolation class:
|
||||
Make sure to use the same :math:`\eta`-function during interpolation as given by the joint :math:`\eta`-distribution passed to the constructor.
|
||||
|
||||
.. Note::
|
||||
Make sure to use resonable energy bins, when constructing the joint distribution. If data is too sparse for a given energy the interpolation will lead to erreneous results.
|
||||
Make sure to use reasonable energy bins, when constructing the joint distribution. If data is too sparse for a given energy the interpolation will lead to erroneous results.
|
||||
|
||||
.. doxygenclass:: aare::Interpolator
|
||||
:members:
|
||||
|
||||
@@ -12,7 +12,7 @@ The structure of the file is:
|
||||
* ...
|
||||
|
||||
There is no metadata indicating number of frames or the size of the image, but this
|
||||
will be infered by this reader.
|
||||
will be inferred by this reader.
|
||||
|
||||
.. doxygenstruct:: aare::JungfrauDataHeader
|
||||
:members:
|
||||
|
||||
@@ -38,7 +38,7 @@ C++ functions that support the ClusterVector or to view it as a numpy array.
|
||||
Below is the API of the ClusterVector_Cluster3x3i but all variants share the same API.
|
||||
|
||||
.. autoclass:: aare._aare.ClusterVector_Cluster3x3i
|
||||
:special-members: __init__
|
||||
:special-members: __init__, __call__
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
@@ -111,7 +111,7 @@ Interpolation class for :math:`\eta`-Interpolation
|
||||
The interpolation might lead to erroneous photon positions for clusters at the boarders of a frame. Make sure to filter out such cases.
|
||||
|
||||
.. Note::
|
||||
Make sure to use resonable energy bins, when constructing the joint distribution. If data is too sparse for a given energy the interpolation will lead to erreneous results.
|
||||
Make sure to use reasonable energy bins, when constructing the joint distribution. If data is too sparse for a given energy the interpolation will lead to erreneous results.
|
||||
|
||||
|
||||
.. py:currentmodule:: aare
|
||||
|
||||
+36
-30
@@ -1,12 +1,12 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
#pragma once
|
||||
#include <stdexcept>
|
||||
#include "aare/Models.hpp"
|
||||
#include "aare/NDView.hpp"
|
||||
#include <Minuit2/FCNGradientBase.h>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <Minuit2/FCNGradientBase.h>
|
||||
#include "aare/NDView.hpp"
|
||||
#include "aare/Models.hpp"
|
||||
|
||||
namespace aare {
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace func {
|
||||
*
|
||||
* By providing analytic gradients we avoid 2*npar extra function evaluations
|
||||
* per Minuit step that would otherwise be spent on finite differences.
|
||||
*
|
||||
*
|
||||
* @throws std::invalid_argument if par.size() != Model::npar.
|
||||
*
|
||||
* Invalid model parameters do not throw; they return a large penalty
|
||||
@@ -37,31 +37,32 @@ namespace func {
|
||||
*/
|
||||
template <class Model>
|
||||
class Chi2Model1DGrad : public ROOT::Minuit2::FCNGradientBase {
|
||||
public:
|
||||
Chi2Model1DGrad(NDView<double, 1> x,
|
||||
NDView<double, 1> y)
|
||||
public:
|
||||
Chi2Model1DGrad(NDView<double, 1> x, NDView<double, 1> y)
|
||||
: x_(x), y_(y), s_(), weighted_(false) {}
|
||||
|
||||
Chi2Model1DGrad(NDView<double, 1> x,
|
||||
NDView<double, 1> y,
|
||||
Chi2Model1DGrad(NDView<double, 1> x, NDView<double, 1> y,
|
||||
NDView<double, 1> y_err)
|
||||
: x_(x), y_(y), s_(y_err), weighted_(true) {}
|
||||
|
||||
~Chi2Model1DGrad() override = default;
|
||||
|
||||
double operator()(const std::vector<double>& par) const override {
|
||||
double operator()(const std::vector<double> &par) const override {
|
||||
if (par.size() != Model::npar) {
|
||||
throw std::invalid_argument("Chi2Model1DGrad: wrong parameter vector size.");
|
||||
throw std::invalid_argument(
|
||||
"Chi2Model1DGrad: wrong parameter vector size.");
|
||||
}
|
||||
|
||||
if (!Model::is_valid(par)) return 1e20;
|
||||
|
||||
if (!Model::is_valid(par))
|
||||
return 1e20;
|
||||
|
||||
double chi2 = 0.0;
|
||||
|
||||
if (weighted_) {
|
||||
for (ssize_t i = 0; i < x_.size(); ++i) {
|
||||
const double si = s_[i];
|
||||
if (si == 0.0) continue;
|
||||
if (si == 0.0)
|
||||
continue;
|
||||
|
||||
const double f_i = Model::eval(x_[i], par);
|
||||
const double r_i = y_[i] - f_i;
|
||||
@@ -78,13 +79,16 @@ public:
|
||||
return chi2;
|
||||
}
|
||||
|
||||
std::vector<double> Gradient(const std::vector<double>& par) const override {
|
||||
std::vector<double>
|
||||
Gradient(const std::vector<double> &par) const override {
|
||||
if (par.size() != Model::npar) {
|
||||
throw std::invalid_argument("Chi2Model1DGrad: wrong parameter vector size.");
|
||||
throw std::invalid_argument(
|
||||
"Chi2Model1DGrad: wrong parameter vector size.");
|
||||
}
|
||||
|
||||
|
||||
std::vector<double> grad(Model::npar, 0.0);
|
||||
if (!Model::is_valid(par)) return grad;
|
||||
if (!Model::is_valid(par))
|
||||
return grad;
|
||||
|
||||
std::array<double, Model::npar> df{};
|
||||
double f_i = 0.0;
|
||||
@@ -92,12 +96,13 @@ public:
|
||||
if (weighted_) {
|
||||
for (ssize_t i = 0; i < x_.size(); ++i) {
|
||||
const double si = s_[i];
|
||||
if (si == 0.0) continue;
|
||||
if (si == 0.0)
|
||||
continue;
|
||||
|
||||
Model::eval_and_grad(x_[i], par, f_i, df);
|
||||
|
||||
const double r_i = y_[i] - f_i;
|
||||
const double c = -2.0 * r_i / (si * si);
|
||||
const double c = -2.0 * r_i / (si * si);
|
||||
|
||||
for (std::size_t k = 0; k < Model::npar; ++k) {
|
||||
grad[k] += c * df[k];
|
||||
@@ -108,7 +113,7 @@ public:
|
||||
Model::eval_and_grad(x_[i], par, f_i, df);
|
||||
|
||||
const double r_i = y_[i] - f_i;
|
||||
const double c = -2.0 * r_i;
|
||||
const double c = -2.0 * r_i;
|
||||
|
||||
for (std::size_t k = 0; k < Model::npar; ++k) {
|
||||
grad[k] += c * df[k];
|
||||
@@ -119,10 +124,11 @@ public:
|
||||
return grad;
|
||||
}
|
||||
|
||||
/** @brief Error definition: 1.0 for chi-squared (delta_chi2 = 1 -> 1-sigma). */
|
||||
/** @brief Error definition: 1.0 for chi-squared (delta_chi2 = 1 ->
|
||||
* 1-sigma). */
|
||||
double Up() const override { return 1.0; }
|
||||
|
||||
private:
|
||||
private:
|
||||
NDView<double, 1> x_;
|
||||
NDView<double, 1> y_;
|
||||
NDView<double, 1> s_;
|
||||
@@ -131,12 +137,12 @@ private:
|
||||
|
||||
// ── Convenient aliases ──────────────────────────────────────────────
|
||||
|
||||
using Chi2Gaussian = Chi2Model1DGrad<aare::model::Gaussian>;
|
||||
using Chi2RisingScurve = Chi2Model1DGrad<aare::model::RisingScurve>;
|
||||
using Chi2Gaussian = Chi2Model1DGrad<aare::model::Gaussian>;
|
||||
using Chi2RisingScurve = Chi2Model1DGrad<aare::model::RisingScurve>;
|
||||
using Chi2FallingScurve = Chi2Model1DGrad<aare::model::FallingScurve>;
|
||||
using Chi2Pol1 = Chi2Model1DGrad<aare::model::Pol1>;
|
||||
using Chi2Pol2 = Chi2Model1DGrad<aare::model::Pol2>;
|
||||
using Chi2Pol1 = Chi2Model1DGrad<aare::model::Pol1>;
|
||||
using Chi2Pol2 = Chi2Model1DGrad<aare::model::Pol2>;
|
||||
|
||||
} // namespace aare::func
|
||||
} // namespace func
|
||||
|
||||
} // aare
|
||||
} // namespace aare
|
||||
@@ -17,7 +17,7 @@ template <class ItemType> class CircularFifo {
|
||||
aare::ProducerConsumerQueue<ItemType> filled_slots;
|
||||
|
||||
public:
|
||||
CircularFifo() : CircularFifo(100){};
|
||||
CircularFifo() : CircularFifo(100) {};
|
||||
CircularFifo(uint32_t size)
|
||||
: fifo_size(size), free_slots(size + 1), filled_slots(size + 1) {
|
||||
|
||||
|
||||
@@ -59,6 +59,27 @@ class ClusterVector<Cluster<T, ClusterSizeX, ClusterSizeY, CoordType>> {
|
||||
other.m_data.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a copy of the clustervector by filtering clusters in the
|
||||
* ClusterVector using a boolean mask.
|
||||
* @param mask boolean 1d mask
|
||||
* @return ClusterVector containing only the clusters where the mask is
|
||||
* true
|
||||
*/
|
||||
ClusterVector operator()(NDView<bool, 1> mask) {
|
||||
if (static_cast<size_t>(mask.size()) != m_data.size()) {
|
||||
throw std::runtime_error(
|
||||
LOCATION + "Mask size does not match number of clusters");
|
||||
}
|
||||
ClusterVector result(capacity(), frame_number());
|
||||
for (size_t i = 0; i < m_data.size(); ++i) {
|
||||
if (mask(i)) {
|
||||
result.push_back(m_data[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Move assignment operator
|
||||
ClusterVector &operator=(ClusterVector &&other) noexcept {
|
||||
if (this != &other) {
|
||||
|
||||
+66
-66
@@ -5,17 +5,17 @@
|
||||
#include <fmt/core.h>
|
||||
#include <vector>
|
||||
|
||||
#include "aare/utils/par.hpp"
|
||||
#include "aare/utils/task.hpp"
|
||||
#include "aare/NDArray.hpp"
|
||||
#include "aare/Chi2.hpp"
|
||||
#include "aare/FitModel.hpp"
|
||||
#include "aare/NDArray.hpp"
|
||||
#include "aare/utils/par.hpp"
|
||||
#include "aare/utils/task.hpp"
|
||||
|
||||
#include "Minuit2/FunctionMinimum.h"
|
||||
#include "Minuit2/MnMigrad.h"
|
||||
#include "Minuit2/MnHesse.h"
|
||||
#include "Minuit2/MnUserParameters.h"
|
||||
#include "Minuit2/MnMigrad.h"
|
||||
#include "Minuit2/MnPrint.h"
|
||||
#include "Minuit2/MnUserParameters.h"
|
||||
|
||||
namespace aare {
|
||||
|
||||
@@ -34,7 +34,6 @@ NDArray<double, 1> scurve2(NDView<double, 1> x, NDView<double, 1> par);
|
||||
|
||||
} // namespace func
|
||||
|
||||
|
||||
static constexpr int DEFAULT_NUM_THREADS = 4;
|
||||
|
||||
/**
|
||||
@@ -80,7 +79,6 @@ void fit_gaus(NDView<double, 1> x, NDView<double, 3> y, NDView<double, 3> y_err,
|
||||
NDView<double, 3> par_out, NDView<double, 3> par_err_out,
|
||||
NDView<double, 2> chi2_out, int n_threads = DEFAULT_NUM_THREADS);
|
||||
|
||||
|
||||
NDArray<double, 1> fit_pol1(NDView<double, 1> x, NDView<double, 1> y);
|
||||
|
||||
NDArray<double, 3> fit_pol1(NDView<double, 1> x, NDView<double, 3> y,
|
||||
@@ -136,7 +134,8 @@ void fit_scurve2(NDView<double, 1> x, NDView<double, 3> y,
|
||||
* - Neither: both value and step size auto-filled from data.
|
||||
*
|
||||
* @tparam Model Model struct (Gaussian, RisingScurve, …).
|
||||
* @tparam FCN Chi2 functor type (Chi2Model1D or Chi2Model1DGrad instantiation).
|
||||
* @tparam FCN Chi2 functor type (Chi2Model1D or Chi2Model1DGrad
|
||||
* instantiation).
|
||||
*
|
||||
* @param model The FitModel configuration (read-only).
|
||||
* @param upar_local Thread-local clone of model.upar(). Modified in place.
|
||||
@@ -148,20 +147,19 @@ void fit_scurve2(NDView<double, 1> x, NDView<double, 3> y,
|
||||
* - compute_errors: [p0..pN, err0..errN, chi2] -> 2*npar + 1
|
||||
* - otherwise: [p0..pN, chi2] -> npar + 1
|
||||
*/
|
||||
template<typename Model, typename FCN>
|
||||
NDArray<double, 1> fit_pixel(const FitModel<Model>& model,
|
||||
ROOT::Minuit2::MnUserParameters& upar_local,
|
||||
NDView<double, 1> x,
|
||||
NDView<double, 1> y,
|
||||
NDView<double, 1> y_err) {
|
||||
template <typename Model, typename FCN>
|
||||
NDArray<double, 1> fit_pixel(const FitModel<Model> &model,
|
||||
ROOT::Minuit2::MnUserParameters &upar_local,
|
||||
NDView<double, 1> x, NDView<double, 1> y,
|
||||
NDView<double, 1> y_err) {
|
||||
|
||||
constexpr std::size_t npar = Model::npar;
|
||||
constexpr std::size_t npar = Model::npar;
|
||||
const bool want_errors = model.compute_errors();
|
||||
const ssize_t result_size = want_errors ? (2 * npar + 1) : (npar + 1);
|
||||
|
||||
// ──── automatic parameter estimation ─────────────
|
||||
auto start = Model::estimate_par(x,y);
|
||||
|
||||
auto start = Model::estimate_par(x, y);
|
||||
|
||||
// dead / degenerate pixel guard
|
||||
if (!Model::is_valid(std::vector<double>(start.begin(), start.end()))) {
|
||||
return NDArray<double, 1>({result_size}, 0.0);
|
||||
@@ -170,18 +168,18 @@ NDArray<double, 1> fit_pixel(const FitModel<Model>& model,
|
||||
// ──── data-range statistics for step sizes ─────────────
|
||||
double x_range, y_range, slope_scale;
|
||||
model::compute_ranges(x, y, x_range, y_range, slope_scale);
|
||||
|
||||
|
||||
std::array<double, npar> steps{};
|
||||
Model::compute_steps(start, x_range, y_range, slope_scale, steps);
|
||||
|
||||
// ── apply auto-estimates respecting user precedence ─────────────
|
||||
for(std::size_t i = 0; i < npar; ++i){
|
||||
for (std::size_t i = 0; i < npar; ++i) {
|
||||
// fixed: do not touch at all
|
||||
if(model.is_user_fixed(i)){
|
||||
if (model.is_user_fixed(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!model.is_user_start(i)){
|
||||
if (!model.is_user_start(i)) {
|
||||
upar_local.SetValue(i, start[i]);
|
||||
}
|
||||
|
||||
@@ -193,7 +191,8 @@ NDArray<double, 1> fit_pixel(const FitModel<Model>& model,
|
||||
|
||||
// ──── run minimizer ────────
|
||||
ROOT::Minuit2::MnMigrad migrad(chi2, upar_local, model.strategy());
|
||||
ROOT::Minuit2::FunctionMinimum min = migrad(model.max_calls(), model.tolerance());
|
||||
ROOT::Minuit2::FunctionMinimum min =
|
||||
migrad(model.max_calls(), model.tolerance());
|
||||
|
||||
if (!min.IsValid())
|
||||
return NDArray<double, 1>({result_size}, 0.0);
|
||||
@@ -202,20 +201,20 @@ NDArray<double, 1> fit_pixel(const FitModel<Model>& model,
|
||||
if (want_errors) {
|
||||
ROOT::Minuit2::MnHesse hesse;
|
||||
hesse(chi2, min);
|
||||
|
||||
const auto& values = min.UserState().Params();
|
||||
const auto& errors = min.UserState().Errors();
|
||||
|
||||
|
||||
const auto &values = min.UserState().Params();
|
||||
const auto &errors = min.UserState().Errors();
|
||||
|
||||
NDArray<double, 1> result({result_size});
|
||||
for (std::size_t k = 0; k < npar; ++k) {
|
||||
result[k] = values[k];
|
||||
result[k] = values[k];
|
||||
result[npar + k] = errors[k];
|
||||
}
|
||||
result[2 * npar] = min.Fval();
|
||||
return result;
|
||||
}
|
||||
|
||||
const auto& values = min.UserState().Params();
|
||||
|
||||
const auto &values = min.UserState().Params();
|
||||
NDArray<double, 1> result({result_size});
|
||||
for (std::size_t k = 0; k < npar; ++k)
|
||||
result[k] = values[k];
|
||||
@@ -225,21 +224,16 @@ NDArray<double, 1> fit_pixel(const FitModel<Model>& model,
|
||||
|
||||
// ── self-contained for 1D / standalone use ─────────
|
||||
template <typename Model, typename FCN>
|
||||
NDArray<double, 1> fit_pixel(const FitModel<Model>& model,
|
||||
NDView<double, 1> x,
|
||||
NDView<double, 1> y,
|
||||
NDView<double, 1> y_err)
|
||||
{
|
||||
NDArray<double, 1> fit_pixel(const FitModel<Model> &model, NDView<double, 1> x,
|
||||
NDView<double, 1> y, NDView<double, 1> y_err) {
|
||||
auto upar_local = model.upar();
|
||||
return fit_pixel<Model, FCN>(model, upar_local, x, y, y_err);
|
||||
}
|
||||
|
||||
// Overload: uncertainties not provided
|
||||
template <typename Model, typename FCN>
|
||||
NDArray<double, 1> fit_pixel(const FitModel<Model>& model,
|
||||
NDView<double, 1> x,
|
||||
NDView<double, 1> y)
|
||||
{
|
||||
NDArray<double, 1> fit_pixel(const FitModel<Model> &model, NDView<double, 1> x,
|
||||
NDView<double, 1> y) {
|
||||
auto upar_local = model.upar();
|
||||
return fit_pixel<Model, FCN>(model, upar_local, x, y, NDView<double, 1>{});
|
||||
}
|
||||
@@ -257,68 +251,74 @@ NDArray<double, 1> fit_pixel(const FitModel<Model>& model,
|
||||
* @param model Fit configuration shared by all pixels.
|
||||
* @param x Scan points, shape `(n_scan)`.
|
||||
* @param y Measured values, shape `(rows, cols, n_scan)`.
|
||||
* @param y_err Uncertainties, same shape as y, or empty for unweighted fits.
|
||||
* @param y_err Uncertainties, same shape as y, or empty for unweighted
|
||||
* fits.
|
||||
* @param par_out Output parameters, shape `(rows, cols, npar)`.
|
||||
* @param err_out Output parameter errors, shape `(rows, cols, npar)`, if used.
|
||||
* @param chi2_out Output chi-squared / objective values, shape `(rows, cols)`.
|
||||
* @param err_out Output parameter errors, shape `(rows, cols, npar)`, if
|
||||
* used.
|
||||
* @param chi2_out Output chi-squared / objective values, shape `(rows,
|
||||
* cols)`.
|
||||
* @param n_threads Number of threads used to split rows.
|
||||
*
|
||||
*/
|
||||
template <typename Model, typename FCN>
|
||||
void fit_3d(const FitModel<Model>& model,
|
||||
NDView<double, 1> x, // (n_scan)
|
||||
NDView<double, 3> y, // (rows, cols, n_scan)
|
||||
NDView<double, 3> y_err, // (rows, cols, n_scan) or empty for unweighted fit
|
||||
NDView<double, 3> par_out,
|
||||
NDView<double, 3> err_out,
|
||||
NDView<double, 2> chi2_out,
|
||||
int n_threads)
|
||||
{
|
||||
void fit_3d(
|
||||
const FitModel<Model> &model, NDView<double, 1> x, // (n_scan)
|
||||
NDView<double, 3> y, // (rows, cols, n_scan)
|
||||
NDView<double, 3> y_err, // (rows, cols, n_scan) or empty for unweighted fit
|
||||
NDView<double, 3> par_out, NDView<double, 3> err_out,
|
||||
NDView<double, 2> chi2_out, int n_threads) {
|
||||
const std::size_t npar = Model::npar;
|
||||
|
||||
// ──── checks ───────
|
||||
if (x.size() != y.shape(2))
|
||||
throw std::runtime_error("fit_3d: x.size() must match y.shape(2).");
|
||||
|
||||
if (par_out.shape(0) != y.shape(0) || par_out.shape(1) != y.shape(1) || par_out.shape(2) != npar)
|
||||
if (par_out.shape(0) != y.shape(0) || par_out.shape(1) != y.shape(1) ||
|
||||
par_out.shape(2) != npar)
|
||||
throw std::runtime_error("par_out must have shape [rows, cols, npar].");
|
||||
|
||||
if (chi2_out.shape(0) != y.shape(0) || chi2_out.shape(1) != y.shape(1))
|
||||
throw std::runtime_error("chi2_out must have shape [rows, cols].");
|
||||
|
||||
|
||||
const bool has_errors = (y_err.size() > 0);
|
||||
const bool want_par_errors = (err_out.size() > 0) && model.compute_errors();
|
||||
|
||||
if (has_errors) {
|
||||
if (y.shape(0) != y_err.shape(0) || y.shape(1) != y_err.shape(1) || y.shape(2) != y_err.shape(2))
|
||||
throw std::runtime_error("fit_3d: y and y_err must have identical shape.");
|
||||
if (y.shape(0) != y_err.shape(0) || y.shape(1) != y_err.shape(1) ||
|
||||
y.shape(2) != y_err.shape(2))
|
||||
throw std::runtime_error(
|
||||
"fit_3d: y and y_err must have identical shape.");
|
||||
|
||||
if (err_out.shape(0) != y.shape(0) || err_out.shape(1) != y.shape(1) || err_out.shape(2) != npar)
|
||||
throw std::runtime_error("err_out must have shape [rows, cols, npar].");
|
||||
if (err_out.shape(0) != y.shape(0) || err_out.shape(1) != y.shape(1) ||
|
||||
err_out.shape(2) != npar)
|
||||
throw std::runtime_error(
|
||||
"err_out must have shape [rows, cols, npar].");
|
||||
}
|
||||
|
||||
// ──── parallel dispatch ───────
|
||||
auto process = [&](ssize_t first_row, ssize_t last_row) {
|
||||
|
||||
// one clone per thread
|
||||
auto upar_local = model.upar();
|
||||
// one clone per thread
|
||||
auto upar_local = model.upar();
|
||||
|
||||
for (ssize_t row = first_row; row < last_row; row++) {
|
||||
for (ssize_t col = 0; col < y.shape(1); col++) {
|
||||
|
||||
NDView<double, 1> values(&y(row, col, 0), {y.shape(2)});
|
||||
NDView<double, 1> errors = has_errors
|
||||
? NDView<double, 1>(&y_err(row, col, 0), {y_err.shape(2)})
|
||||
: NDView<double, 1>{};
|
||||
NDView<double, 1> errors =
|
||||
has_errors ? NDView<double, 1>(&y_err(row, col, 0),
|
||||
{y_err.shape(2)})
|
||||
: NDView<double, 1>{};
|
||||
|
||||
auto res = fit_pixel<Model, FCN>(model, upar_local, x, values, errors);
|
||||
|
||||
for(std::size_t k = 0; k < npar; ++k) {
|
||||
auto res =
|
||||
fit_pixel<Model, FCN>(model, upar_local, x, values, errors);
|
||||
|
||||
for (std::size_t k = 0; k < npar; ++k) {
|
||||
par_out(row, col, k) = res(k);
|
||||
}
|
||||
|
||||
if (want_par_errors) {
|
||||
for(std::size_t k = 0; k < npar; ++k){
|
||||
for (std::size_t k = 0; k < npar; ++k) {
|
||||
err_out(row, col, k) = res(npar + k);
|
||||
}
|
||||
chi2_out(row, col) = res(2 * npar);
|
||||
|
||||
+72
-39
@@ -1,17 +1,15 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
#include "aare/Models.hpp"
|
||||
#include <type_traits>
|
||||
|
||||
#include "Minuit2/MnUserParameters.h"
|
||||
#include "Minuit2/MnStrategy.h"
|
||||
#include "Minuit2/MnUserParameters.h"
|
||||
|
||||
namespace aare {
|
||||
|
||||
|
||||
template <typename Model>
|
||||
class FitModel {
|
||||
template <typename Model> class FitModel {
|
||||
ROOT::Minuit2::MnUserParameters upar_;
|
||||
ROOT::Minuit2::MnStrategy strategy_;
|
||||
unsigned int max_calls_;
|
||||
@@ -21,45 +19,51 @@ class FitModel {
|
||||
std::array<bool, Model::npar> user_fixed_{};
|
||||
std::array<bool, Model::npar> user_start_{};
|
||||
|
||||
public:
|
||||
/** @brief Safely resolve a parameter name to its index. */
|
||||
unsigned int checked_index(const std::string &name) const {
|
||||
for (std::size_t i = 0; i < npar; ++i) {
|
||||
if (upar_.Name(i) == name)
|
||||
return static_cast<unsigned int>(i);
|
||||
}
|
||||
throw std::runtime_error("FitModel: unknown parameter name '" + name +
|
||||
"'");
|
||||
}
|
||||
|
||||
public:
|
||||
static constexpr std::size_t npar = Model::npar;
|
||||
|
||||
/**
|
||||
* @brief Construct a fit model with sensible defaults.
|
||||
*
|
||||
* @param strategy Minuit2 strategy level (0 = fast/gradient, 1 = default).
|
||||
* @param strategy Minuit2 strategy level (0 = fast/gradient, 1 =
|
||||
* default).
|
||||
* @param max_calls Maximum FCN calls per pixel minimisation.
|
||||
* @param tolerance Minuit2 EDM tolerance.
|
||||
* @param compute_errors If true, run MnHesse after minimisation.
|
||||
*/
|
||||
FitModel(unsigned int strategy = 0,
|
||||
unsigned int max_calls = 100,
|
||||
double tolerance = 0.5,
|
||||
bool compute_errors = false)
|
||||
: strategy_(strategy),
|
||||
max_calls_(max_calls),
|
||||
tolerance_(tolerance),
|
||||
compute_errors_(compute_errors)
|
||||
{
|
||||
for(std::size_t i = 0; i < npar; ++i){
|
||||
FitModel(unsigned int strategy = 0, unsigned int max_calls = 100,
|
||||
double tolerance = 0.5, bool compute_errors = false)
|
||||
: strategy_(strategy), max_calls_(max_calls), tolerance_(tolerance),
|
||||
compute_errors_(compute_errors) {
|
||||
for (std::size_t i = 0; i < npar; ++i) {
|
||||
const auto pi = Model::param_info[i];
|
||||
const bool has_lo = std::isfinite(pi.default_lo);
|
||||
const bool has_hi = std::isfinite(pi.default_hi);
|
||||
|
||||
// Add parameters and valid bounds
|
||||
if (has_lo && has_hi){
|
||||
if (has_lo && has_hi) {
|
||||
upar_.Add(pi.name, 0.0, 1.0, pi.default_lo, pi.default_hi);
|
||||
} else if (has_lo) {
|
||||
upar_.Add(pi.name, 0.0, 1.0, pi.default_lo, 1e6);
|
||||
} else {
|
||||
upar_.Add(pi.name, 0.0, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Set lower and upper bounds for parameter idx.*/
|
||||
void SetParLimits(unsigned int idx, double lo, double hi) {
|
||||
upar_.SetLimits(idx, lo, hi);
|
||||
void SetParLimits(unsigned int idx, double lo, double hi) {
|
||||
upar_.SetLimits(idx, lo, hi);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,38 +71,67 @@ public:
|
||||
*
|
||||
* Excluded from minimisation. Automatic estimates will not touch it.
|
||||
*/
|
||||
void FixParameter(unsigned int idx, double val) {
|
||||
upar_.SetValue(idx, val);
|
||||
void FixParameter(unsigned int idx, double val) {
|
||||
SetParameter(idx, val);
|
||||
upar_.Fix(idx);
|
||||
user_start_[idx] = true;
|
||||
user_fixed_[idx] = true;
|
||||
}
|
||||
|
||||
/** @brief Release a previously fixed parameter, re-enabling auto estimates. */
|
||||
|
||||
/** @brief Release a previously fixed parameter, re-enabling auto estimates.
|
||||
*/
|
||||
void ReleaseParameter(unsigned int idx) {
|
||||
upar_.Release(idx);
|
||||
user_fixed_[idx] = false;
|
||||
}
|
||||
|
||||
void ReleaseParameter(const std::string &name) {
|
||||
ReleaseParameter(checked_index(name));
|
||||
}
|
||||
|
||||
/** @brief Set an explicit starting value for parameter idx.*/
|
||||
void SetParameter(unsigned int idx, double val) {
|
||||
upar_.SetValue(idx, val);
|
||||
user_start_[idx] = true;
|
||||
}
|
||||
|
||||
void SetMaxCalls(unsigned int n) { max_calls_ = n; }
|
||||
void SetTolerance(double t) { tolerance_ = t; }
|
||||
void SetComputeErrors(bool b) { compute_errors_ = b; }
|
||||
|
||||
void SetParameter(const std::string &name, double val) {
|
||||
// go through index to maintain user_start_ bookkeeping
|
||||
SetParameter(checked_index(name), val);
|
||||
}
|
||||
|
||||
void FixParameter(const std::string &name, double val) {
|
||||
// go through index to maintain user_fixed_ bookkeeping
|
||||
FixParameter(checked_index(name), val);
|
||||
}
|
||||
|
||||
void SetParLimits(const std::string &name, double lo, double hi) {
|
||||
SetParLimits(checked_index(name), lo, hi);
|
||||
}
|
||||
|
||||
std::string GetParName(unsigned int idx) const {
|
||||
return upar_.GetName(idx);
|
||||
}
|
||||
|
||||
std::vector<std::string> GetParNames() const {
|
||||
std::vector<std::string> names;
|
||||
for (std::size_t i = 0; i < npar; ++i)
|
||||
names.push_back(GetParName(i));
|
||||
return names;
|
||||
}
|
||||
static constexpr std::size_t GetNpar() noexcept { return npar; }
|
||||
|
||||
void SetMaxCalls(unsigned int n) { max_calls_ = n; }
|
||||
void SetTolerance(double t) { tolerance_ = t; }
|
||||
void SetComputeErrors(bool b) { compute_errors_ = b; }
|
||||
|
||||
// accessors
|
||||
const ROOT::Minuit2::MnUserParameters& upar() const { return upar_; }
|
||||
const ROOT::Minuit2::MnStrategy& strategy() const { return strategy_; }
|
||||
unsigned int max_calls() const { return max_calls_; }
|
||||
double tolerance() const { return tolerance_; }
|
||||
bool compute_errors() const { return compute_errors_; }
|
||||
bool is_user_fixed(unsigned int idx) const { return user_fixed_[idx]; }
|
||||
bool is_user_start(unsigned int idx) const { return user_start_[idx]; }
|
||||
const ROOT::Minuit2::MnUserParameters &upar() const { return upar_; }
|
||||
const ROOT::Minuit2::MnStrategy &strategy() const { return strategy_; }
|
||||
unsigned int max_calls() const { return max_calls_; }
|
||||
double tolerance() const { return tolerance_; }
|
||||
bool compute_errors() const { return compute_errors_; }
|
||||
bool is_user_fixed(unsigned int idx) const { return user_fixed_[idx]; }
|
||||
bool is_user_start(unsigned int idx) const { return user_start_[idx]; }
|
||||
};
|
||||
|
||||
|
||||
} // namespace aare
|
||||
} // namespace aare
|
||||
@@ -171,11 +171,14 @@ Coordinate2D Interpolator::transform_eta_values(const Eta2<T> &eta) const {
|
||||
|
||||
if (static_cast<ssize_t>(ix) >= m_etabinsx.size() - 1 ||
|
||||
static_cast<ssize_t>(iy) >= m_etabinsy.size() - 1 ||
|
||||
static_cast<ssize_t>(ie) >= m_energy_bins.size() - 1)
|
||||
throw std::runtime_error(
|
||||
fmt::format("Eta values out of bounds of eta distribution: eta.x = "
|
||||
"{:.4f}, eta.y = {:.4f}, energy = {:.4f}",
|
||||
eta.x, eta.y, eta.sum));
|
||||
static_cast<ssize_t>(ie) >= m_energy_bins.size() - 1) {
|
||||
throw std::runtime_error(fmt::format(
|
||||
"Eta values (eta.x = {:4f}, eta.y = {:4f}, energy = {}) out of "
|
||||
"bounds of eta distribution with largest values: (eta.x = {:4f}, "
|
||||
"eta.y = {:4f}, energy = {:4f})",
|
||||
eta.x, eta.y, eta.sum, *(m_etabinsx.end() - 1),
|
||||
*(m_etabinsy.end() - 1), *(m_energy_bins.end() - 1)));
|
||||
}
|
||||
|
||||
// TODO: bilinear interpolation only works if all bins have a size > 1 -
|
||||
// otherwise bilinear interpolation with zero values which skew the
|
||||
|
||||
+194
-178
@@ -1,18 +1,40 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
#pragma once
|
||||
|
||||
#include "aare/NDView.hpp"
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
#include "aare/NDView.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace aare::model {
|
||||
|
||||
inline constexpr double inv_sqrt2 = 0.70710678118654752440;
|
||||
inline constexpr double inv_sqrt2 = 0.70710678118654752440;
|
||||
inline constexpr double inv_sqrt_2pi = 0.39894228040143267794;
|
||||
|
||||
inline double fast_erf(double x) {
|
||||
// Abramowitz–Stegun Handbook of Mathematical Functions
|
||||
// erf approximation with max error ~1.5e-7, faster than std::erf.
|
||||
|
||||
const double a1 = 0.254829592;
|
||||
const double a2 = -0.284496736;
|
||||
const double a3 = 1.421413741;
|
||||
const double a4 = -1.453152027;
|
||||
const double a5 = 1.061405429;
|
||||
const double p = 0.3275911;
|
||||
|
||||
const int sign = x < 0 ? -1 : 1;
|
||||
x = std::abs(x);
|
||||
|
||||
// 7.1.26
|
||||
const double t = 1.0 / (1.0 + p * x);
|
||||
const double y =
|
||||
1.0 -
|
||||
(((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t) * std::exp(-x * x);
|
||||
|
||||
return sign * y;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Per-parameter metadata: name and optional default bounds.
|
||||
@@ -21,11 +43,11 @@ inline constexpr double inv_sqrt_2pi = 0.39894228040143267794;
|
||||
* Unbounded directions use ±no_bound as sentinels.
|
||||
*/
|
||||
struct ParamInfo {
|
||||
const char* name; // name of parameter
|
||||
double default_lo; // lower bound value
|
||||
double default_hi; // upper bound value
|
||||
const char *name; // name of parameter
|
||||
double default_lo; // lower bound value
|
||||
double default_hi; // upper bound value
|
||||
};
|
||||
|
||||
|
||||
inline constexpr double no_bound = std::numeric_limits<double>::infinity();
|
||||
|
||||
/**
|
||||
@@ -33,18 +55,15 @@ inline constexpr double no_bound = std::numeric_limits<double>::infinity();
|
||||
*
|
||||
* Model-independent, called once per pixel.
|
||||
*/
|
||||
inline void compute_ranges(NDView<double, 1> x,
|
||||
NDView<double, 1> y,
|
||||
double& x_range,
|
||||
double& y_range,
|
||||
double& slope_scale)
|
||||
{
|
||||
inline void compute_ranges(NDView<double, 1> x, NDView<double, 1> y,
|
||||
double &x_range, double &y_range,
|
||||
double &slope_scale) {
|
||||
const auto [x_min, x_max] = std::minmax_element(x.begin(), x.end());
|
||||
const auto [y_min, y_max] = std::minmax_element(y.begin(), y.end());
|
||||
|
||||
x_range = std::max(*x_max - *x_min, 1e-9);
|
||||
y_range = std::max(*y_max - *y_min, 1e-9);
|
||||
|
||||
|
||||
slope_scale = std::max(y_range / x_range, 1e-9);
|
||||
}
|
||||
|
||||
@@ -70,50 +89,45 @@ struct Pol1 {
|
||||
static constexpr std::size_t npar = 2;
|
||||
|
||||
static constexpr std::array<ParamInfo, npar> param_info = {{
|
||||
{"p0", -no_bound, no_bound},
|
||||
{"p1", -no_bound, no_bound},
|
||||
{"p0", -no_bound, no_bound},
|
||||
{"p1", -no_bound, no_bound},
|
||||
}};
|
||||
|
||||
static double eval(double x, const std::vector<double>& par) {
|
||||
static double eval(double x, const std::vector<double> &par) {
|
||||
return par[0] + par[1] * x;
|
||||
}
|
||||
|
||||
static void eval_and_grad(double x,
|
||||
const std::vector<double>& par,
|
||||
double& f,
|
||||
std::array<double, npar>& g)
|
||||
{
|
||||
static void eval_and_grad(double x, const std::vector<double> &par,
|
||||
double &f, std::array<double, npar> &g) {
|
||||
f = par[0] + par[1] * x;
|
||||
|
||||
g[0] = 1.0 ; // df/dp0
|
||||
g[1] = x; // df/dp1
|
||||
g[0] = 1.0; // df/dp0
|
||||
g[1] = x; // df/dp1
|
||||
}
|
||||
|
||||
static bool is_valid([[maybe_unused]] const std::vector<double>& par) {
|
||||
return true; // always valid
|
||||
static bool is_valid([[maybe_unused]] const std::vector<double> &par) {
|
||||
return true; // always valid
|
||||
}
|
||||
|
||||
/** @brief Estimate from endpoints: slope = dy/dx, intercept from first point. */
|
||||
/** @brief Estimate from endpoints: slope = dy/dx, intercept from first
|
||||
* point. */
|
||||
static std::array<double, npar> estimate_par(NDView<double, 1> x,
|
||||
NDView<double, 1> y)
|
||||
{
|
||||
const double dx = x[x.size()-1] - x[0];
|
||||
const double dy = y[y.size()-1] - y[0];
|
||||
const double slope = (std::abs(dx) > 1e-12) ? dy/dx : 0.0;
|
||||
NDView<double, 1> y) {
|
||||
const double dx = x[x.size() - 1] - x[0];
|
||||
const double dy = y[y.size() - 1] - y[0];
|
||||
const double slope = (std::abs(dx) > 1e-12) ? dy / dx : 0.0;
|
||||
const double intercept = y[0] - slope * x[0];
|
||||
|
||||
return {intercept, slope};
|
||||
}
|
||||
|
||||
|
||||
static void compute_steps(const std::array<double, npar>& start,
|
||||
[[maybe_unused]] double x_range, double y_range, double slope_scale,
|
||||
std::array<double, npar>& steps)
|
||||
{
|
||||
static void compute_steps(const std::array<double, npar> &start,
|
||||
[[maybe_unused]] double x_range, double y_range,
|
||||
double slope_scale,
|
||||
std::array<double, npar> &steps) {
|
||||
steps[0] = std::max(0.1 * std::abs(start[0]), 0.1 * y_range);
|
||||
steps[1] = 0.1 * slope_scale;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// _____________________________________________________________________
|
||||
@@ -124,7 +138,7 @@ struct Pol1 {
|
||||
/**
|
||||
* @brief Polynomial fuction of degree 2
|
||||
*
|
||||
* f(x) = p0 + p1 * x + p2 * x * x
|
||||
* f(x) = p0 + p1 * x + p2 * x * x
|
||||
*
|
||||
* Parameters:
|
||||
* par[0] = p0 (constant term)
|
||||
@@ -140,29 +154,26 @@ struct Pol2 {
|
||||
static constexpr std::size_t npar = 3;
|
||||
|
||||
static constexpr std::array<ParamInfo, npar> param_info = {{
|
||||
{"p0", -no_bound, no_bound},
|
||||
{"p1", -no_bound, no_bound},
|
||||
{"p2", -no_bound, no_bound},
|
||||
{"p0", -no_bound, no_bound},
|
||||
{"p1", -no_bound, no_bound},
|
||||
{"p2", -no_bound, no_bound},
|
||||
}};
|
||||
|
||||
static double eval(double x, const std::vector<double>& par) {
|
||||
static double eval(double x, const std::vector<double> &par) {
|
||||
return par[0] + par[1] * x + par[2] * x * x;
|
||||
}
|
||||
|
||||
static void eval_and_grad(double x,
|
||||
const std::vector<double>& par,
|
||||
double& f,
|
||||
std::array<double, npar>& g)
|
||||
{
|
||||
static void eval_and_grad(double x, const std::vector<double> &par,
|
||||
double &f, std::array<double, npar> &g) {
|
||||
f = par[0] + par[1] * x + par[2] * x * x;
|
||||
|
||||
g[0] = 1.0 ; // df/dp0
|
||||
g[1] = x; // df/dp1
|
||||
g[2] = x * x; // df/dp2
|
||||
g[0] = 1.0; // df/dp0
|
||||
g[1] = x; // df/dp1
|
||||
g[2] = x * x; // df/dp2
|
||||
}
|
||||
|
||||
static bool is_valid([[maybe_unused]]const std::vector<double>& par) {
|
||||
return true; // always valid
|
||||
static bool is_valid([[maybe_unused]] const std::vector<double> &par) {
|
||||
return true; // always valid
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -184,23 +195,22 @@ struct Pol2 {
|
||||
* when curvature is negligible i.e. slope_e ≈ slope_s -> p2 ≈ 0.
|
||||
*/
|
||||
static std::array<double, npar> estimate_par(NDView<double, 1> x,
|
||||
NDView<double, 1> y)
|
||||
{
|
||||
NDView<double, 1> y) {
|
||||
const ssize_t n = y.size();
|
||||
const ssize_t tail = std::max<ssize_t>(n / 10, 2);
|
||||
|
||||
// start: slope from first 10%
|
||||
const double x_s = (x[0] + x[tail-1]) * 0.5;
|
||||
const double slope_s = (y[tail-1] - y[0]) / (x[tail-1] - x[0]);
|
||||
const double x_s = (x[0] + x[tail - 1]) * 0.5;
|
||||
const double slope_s = (y[tail - 1] - y[0]) / (x[tail - 1] - x[0]);
|
||||
|
||||
// end: slope from last 10%
|
||||
const double x_e = (x[n-tail] + x[n-1]) * 0.5;
|
||||
const double slope_e = (y[n-1] - y[n-tail]) / (x[n-1] - x[n-tail]);
|
||||
const double x_e = (x[n - tail] + x[n - 1]) * 0.5;
|
||||
const double slope_e =
|
||||
(y[n - 1] - y[n - tail]) / (x[n - 1] - x[n - tail]);
|
||||
|
||||
const double dx = x_e - x_s;
|
||||
const double p2 = (std::abs(dx) > 1e-12)
|
||||
? (slope_e - slope_s) / (2.0 * dx)
|
||||
: 0.0;
|
||||
const double p2 =
|
||||
(std::abs(dx) > 1e-12) ? (slope_e - slope_s) / (2.0 * dx) : 0.0;
|
||||
|
||||
// p1 from slope_s = p1 + 2*p2*x_s
|
||||
const double p1 = slope_s - 2.0 * p2 * x_s;
|
||||
@@ -211,11 +221,10 @@ struct Pol2 {
|
||||
return {p0, p1, p2};
|
||||
}
|
||||
|
||||
|
||||
static void compute_steps(const std::array<double, npar>& start,
|
||||
double x_range, double y_range, double slope_scale,
|
||||
std::array<double, npar>& steps)
|
||||
{
|
||||
static void compute_steps(const std::array<double, npar> &start,
|
||||
double x_range, double y_range,
|
||||
double slope_scale,
|
||||
std::array<double, npar> &steps) {
|
||||
steps[0] = std::max(0.1 * std::abs(start[0]), 0.1 * y_range);
|
||||
steps[1] = 0.1 * slope_scale;
|
||||
steps[2] = 0.1 * slope_scale / std::max(x_range, 1e-12);
|
||||
@@ -246,43 +255,41 @@ struct Gaussian {
|
||||
static constexpr std::size_t npar = 3;
|
||||
|
||||
static constexpr std::array<ParamInfo, npar> param_info = {{
|
||||
{"A", -no_bound, no_bound},
|
||||
{"mu", -no_bound, no_bound},
|
||||
{"sig", 1e-12, no_bound},
|
||||
{"A", -no_bound, no_bound},
|
||||
{"mu", -no_bound, no_bound},
|
||||
{"sigma", 1e-12, no_bound},
|
||||
}};
|
||||
|
||||
static double eval(double x, const std::vector<double>& par) {
|
||||
const double A = par[0];
|
||||
const double mu = par[1];
|
||||
static double eval(double x, const std::vector<double> &par) {
|
||||
const double A = par[0];
|
||||
const double mu = par[1];
|
||||
const double sig = par[2];
|
||||
|
||||
const double dx = x - mu;
|
||||
const double dx = x - mu;
|
||||
const double inv_2sig2 = 1.0 / (2.0 * sig * sig);
|
||||
return A * std::exp(-dx * dx * inv_2sig2);
|
||||
}
|
||||
|
||||
static void eval_and_grad(double x,
|
||||
const std::vector<double>& par,
|
||||
double& f,
|
||||
std::array<double, npar>& g)
|
||||
{
|
||||
const double A = par[0];
|
||||
const double mu = par[1];
|
||||
static void eval_and_grad(double x, const std::vector<double> &par,
|
||||
double &f, std::array<double, npar> &g) {
|
||||
const double A = par[0];
|
||||
const double mu = par[1];
|
||||
const double sig = par[2];
|
||||
|
||||
const double dx = x - mu;
|
||||
const double dx = x - mu;
|
||||
const double inv_2sig2 = 1.0 / (2.0 * sig * sig);
|
||||
const double e = std::exp(-dx * dx * inv_2sig2);
|
||||
const double e = std::exp(-dx * dx * inv_2sig2);
|
||||
|
||||
f = A * e;
|
||||
|
||||
g[0] = e; // df/dA
|
||||
g[1] = 2.0 * A * e * dx * inv_2sig2; // df/dmu = A*e*(x-mu)/sig^2
|
||||
g[2] = 2.0 * A * e * dx * dx * inv_2sig2 / sig; // df/dsigma = A*e*(x-mu)^2/sig^3
|
||||
g[0] = e; // df/dA
|
||||
g[1] = 2.0 * A * e * dx * inv_2sig2; // df/dmu = A*e*(x-mu)/sig^2
|
||||
g[2] = 2.0 * A * e * dx * dx * inv_2sig2 /
|
||||
sig; // df/dsigma = A*e*(x-mu)^2/sig^3
|
||||
}
|
||||
|
||||
/** @brief Reject degenerate sigma (zero width). */
|
||||
static bool is_valid(const std::vector<double>& par) {
|
||||
static bool is_valid(const std::vector<double> &par) {
|
||||
return par[2] != 0.0;
|
||||
}
|
||||
|
||||
@@ -294,41 +301,45 @@ struct Gaussian {
|
||||
* sigma = FWHM / 2.35
|
||||
*/
|
||||
static std::array<double, npar> estimate_par(NDView<double, 1> x,
|
||||
NDView<double, 1> y)
|
||||
{
|
||||
NDView<double, 1> y) {
|
||||
// find peak
|
||||
const auto max_it = std::max_element(y.begin(), y.end());
|
||||
const ssize_t i_max = std::distance(y.begin(), max_it);
|
||||
|
||||
const double A = *max_it;
|
||||
const double A = *max_it;
|
||||
const double mu = x[i_max];
|
||||
|
||||
|
||||
// FWHM estimate
|
||||
const double half = A * 0.5;
|
||||
double x_lo = mu, x_hi = mu;
|
||||
for (ssize_t i = i_max; i >= 0; --i)
|
||||
if (y[i] < half) { x_lo = x[i]; break; }
|
||||
if (y[i] < half) {
|
||||
x_lo = x[i];
|
||||
break;
|
||||
}
|
||||
for (ssize_t i = i_max; i < y.size(); ++i)
|
||||
if (y[i] < half) { x_hi = x[i]; break; }
|
||||
if (y[i] < half) {
|
||||
x_hi = x[i];
|
||||
break;
|
||||
}
|
||||
const double sig = std::max((x_hi - x_lo) / 2.35, 1e-6);
|
||||
|
||||
|
||||
return {A, mu, sig};
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Data-driven Minuit step sizes.
|
||||
*/
|
||||
static void compute_steps(const std::array<double, npar>& start,
|
||||
double x_range, double y_range, double /*slope_scale*/,
|
||||
std::array<double, npar>& steps)
|
||||
{
|
||||
static void compute_steps(const std::array<double, npar> &start,
|
||||
double x_range, double y_range,
|
||||
double /*slope_scale*/,
|
||||
std::array<double, npar> &steps) {
|
||||
steps[0] = std::max(0.1 * std::abs(start[0]), 0.1 * y_range);
|
||||
steps[1] = 0.05 * x_range;
|
||||
steps[2] = 0.05 * x_range;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// _____________________________________________________________________
|
||||
//
|
||||
// RisingScurve
|
||||
@@ -338,15 +349,16 @@ struct Gaussian {
|
||||
* @brief Rising S-curve (error-function step) with linear baseline and
|
||||
* post-step slope.
|
||||
*
|
||||
* f(x) = (p0 + p1*x) + 0.5*(1 + erf((x - p2) / (sqrt(2)*p3))) * (p4 + p5*(x - p2))
|
||||
* f(x) = (p0 + p1*x) + 0.5*(1 + erf((x - mu) / (sqrt(2)*sigma))) * (A + C*(x -
|
||||
* mu)))
|
||||
*
|
||||
* Parameters:
|
||||
* par[0] = p0 (baseline offset)
|
||||
* par[1] = p1 (baseline slope)
|
||||
* par[2] = p2 (threshold / inflection point)
|
||||
* par[3] = p3 (transition width, must be > 0)
|
||||
* par[4] = p4 (step amplitude)
|
||||
* par[5] = p5 (post-step slope)
|
||||
* par[2] = mu (inflection point)
|
||||
* par[3] = sigma (transition width, must be > 0)
|
||||
* par[4] = A (step amplitude)
|
||||
* par[5] = C (post-step slope)
|
||||
*/
|
||||
struct RisingScurve {
|
||||
static constexpr std::size_t npar = 6;
|
||||
@@ -354,13 +366,13 @@ struct RisingScurve {
|
||||
static constexpr std::array<ParamInfo, npar> param_info = {{
|
||||
{"p0", -no_bound, no_bound},
|
||||
{"p1", -no_bound, no_bound},
|
||||
{"p2", -no_bound, no_bound},
|
||||
{"p3", 1e-12, no_bound},
|
||||
{"p4", -no_bound, no_bound},
|
||||
{"p5", -no_bound, no_bound},
|
||||
{"mu", -no_bound, no_bound},
|
||||
{"sigma", 1e-12, no_bound},
|
||||
{"A", -no_bound, no_bound},
|
||||
{"C", -no_bound, no_bound},
|
||||
}};
|
||||
|
||||
static double eval(double x, const std::vector<double>& par) {
|
||||
static double eval(double x, const std::vector<double> &par) {
|
||||
const double p0 = par[0];
|
||||
const double p1 = par[1];
|
||||
const double p2 = par[2];
|
||||
@@ -368,8 +380,8 @@ struct RisingScurve {
|
||||
const double p4 = par[4];
|
||||
const double p5 = par[5];
|
||||
|
||||
const double dx = x - p2;
|
||||
const double step = 0.5 * (1.0 + std::erf(dx * inv_sqrt2 / p3));
|
||||
const double dx = x - p2;
|
||||
const double step = 0.5 * (1.0 + fast_erf(dx * inv_sqrt2 / p3));
|
||||
return (p0 + p1 * x) + step * (p4 + p5 * dx);
|
||||
}
|
||||
|
||||
@@ -381,11 +393,8 @@ struct RisingScurve {
|
||||
* dS/dp2 = -(1/sqrt(2*pi)) * exp(-z^2) / p3
|
||||
* dS/dp3 = -(1/sqrt(2*pi)) * exp(-z^2) * (x-p2) / p3^2
|
||||
*/
|
||||
static void eval_and_grad(double x,
|
||||
const std::vector<double>& par,
|
||||
double& f,
|
||||
std::array<double, npar>& g)
|
||||
{
|
||||
static void eval_and_grad(double x, const std::vector<double> &par,
|
||||
double &f, std::array<double, npar> &g) {
|
||||
const double p0 = par[0];
|
||||
const double p1 = par[1];
|
||||
const double p2 = par[2];
|
||||
@@ -393,50 +402,48 @@ struct RisingScurve {
|
||||
const double p4 = par[4];
|
||||
const double p5 = par[5];
|
||||
|
||||
const double dx = x - p2;
|
||||
const double z = dx * inv_sqrt2 / p3;
|
||||
const double step = 0.5 * (1.0 + std::erf(z));
|
||||
const double amp = p4 + p5 * dx;
|
||||
const double dx = x - p2;
|
||||
const double z = dx * inv_sqrt2 / p3;
|
||||
const double step = 0.5 * (1.0 + fast_erf(z));
|
||||
const double amp = p4 + p5 * dx;
|
||||
|
||||
f = (p0 + p1 * x) + step * amp;
|
||||
|
||||
const double e = std::exp(-z * z);
|
||||
const double e = std::exp(-z * z);
|
||||
const double dSdp2 = -inv_sqrt_2pi * e / p3;
|
||||
const double dSdp3 = -inv_sqrt_2pi * e * dx / (p3 * p3);
|
||||
|
||||
g[0] = 1.0; // df/dp0
|
||||
g[1] = x; // df/dp1
|
||||
g[2] = dSdp2 * amp - step * p5; // df/dp2
|
||||
g[3] = dSdp3 * amp; // df/dp3
|
||||
g[4] = step; // df/dp4
|
||||
g[5] = step * dx; // df/dp5
|
||||
g[0] = 1.0; // df/dp0
|
||||
g[1] = x; // df/dp1
|
||||
g[2] = dSdp2 * amp - step * p5; // df/dp2
|
||||
g[3] = dSdp3 * amp; // df/dp3
|
||||
g[4] = step; // df/dp4
|
||||
g[5] = step * dx; // df/dp5
|
||||
}
|
||||
|
||||
/** @brief Reject degenerate width (zero transition width). */
|
||||
static bool is_valid(const std::vector<double>& par) {
|
||||
static bool is_valid(const std::vector<double> &par) {
|
||||
return par[3] != 0.0;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Data-driven initial parameter estimates for a rising S-curve. */
|
||||
static std::array<double, npar> estimate_par(NDView<double, 1> x,
|
||||
NDView<double, 1> y)
|
||||
{
|
||||
NDView<double, 1> y) {
|
||||
const ssize_t n = y.size();
|
||||
|
||||
// baseline: average of first ~10% of points (before turn-on)
|
||||
ssize_t n_base = std::max<ssize_t>(n / 10, 2);
|
||||
double sum_y = 0, sum_xy = 0, sum_x = 0, sum_x2 = 0;
|
||||
for (ssize_t i = 0; i < n_base; ++i) {
|
||||
sum_y += y[i];
|
||||
sum_x += x[i];
|
||||
sum_y += y[i];
|
||||
sum_x += x[i];
|
||||
sum_xy += x[i] * y[i];
|
||||
sum_x2 += x[i] * x[i];
|
||||
}
|
||||
double denom = n_base * sum_x2 - sum_x * sum_x;
|
||||
double p1 = (std::abs(denom) > 1e-30)
|
||||
? (n_base * sum_xy - sum_x * sum_y) / denom
|
||||
: 0.0;
|
||||
? (n_base * sum_xy - sum_x * sum_y) / denom
|
||||
: 0.0;
|
||||
double p0 = (sum_y - p1 * sum_x) / n_base;
|
||||
|
||||
// plateau: average of last ~10%
|
||||
@@ -466,10 +473,16 @@ struct RisingScurve {
|
||||
double y_90 = baseline_at_mid + 0.9 * p4;
|
||||
double x_10 = x[0], x_90 = x[n - 1];
|
||||
for (ssize_t i = 0; i < n; ++i) {
|
||||
if (y[i] >= y_10) { x_10 = x[i]; break; }
|
||||
if (y[i] >= y_10) {
|
||||
x_10 = x[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (ssize_t i = 0; i < n; ++i) {
|
||||
if (y[i] >= y_90) { x_90 = x[i]; break; }
|
||||
if (y[i] >= y_90) {
|
||||
x_90 = x[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// for a Gaussian CDF: 10%-90% width = 2 * 1.2816 * sigma
|
||||
double p3 = std::max((x_90 - x_10) / 2.5631, 1.0);
|
||||
@@ -478,11 +491,11 @@ struct RisingScurve {
|
||||
|
||||
return {p0, p1, p2, p3, p4, p5};
|
||||
}
|
||||
|
||||
static void compute_steps(const std::array<double, npar>& start,
|
||||
double x_range, double y_range, double slope_scale,
|
||||
std::array<double, npar>& steps)
|
||||
{
|
||||
|
||||
static void compute_steps(const std::array<double, npar> &start,
|
||||
double x_range, double y_range,
|
||||
double slope_scale,
|
||||
std::array<double, npar> &steps) {
|
||||
steps[0] = std::max(0.1 * std::abs(start[0]), 0.1 * y_range);
|
||||
steps[1] = 0.1 * slope_scale;
|
||||
steps[2] = 0.05 * x_range;
|
||||
@@ -492,7 +505,6 @@ struct RisingScurve {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// _____________________________________________________________________
|
||||
//
|
||||
// FallingScurve
|
||||
@@ -502,7 +514,8 @@ struct RisingScurve {
|
||||
* @brief Falling S-curve (complementary error-function step) with linear
|
||||
* baseline and post-step slope.
|
||||
*
|
||||
* f(x) = (p0 + p1*x) + 0.5*(1 - erf((x - p2) / (sqrt(2)*p3))) * (p4 + p5*(x - p2))
|
||||
* f(x) = (p0 + p1*x) + 0.5*(1 - erf((x - mu) / (sqrt(2)*sigma))) * (A + C*(x -
|
||||
* mu))
|
||||
*
|
||||
* Parameters are identical to RisingScurve. The only difference is the
|
||||
* sign of the erf term, which flips the step direction (and the signs of
|
||||
@@ -514,13 +527,13 @@ struct FallingScurve {
|
||||
static constexpr std::array<ParamInfo, npar> param_info = {{
|
||||
{"p0", -no_bound, no_bound},
|
||||
{"p1", -no_bound, no_bound},
|
||||
{"p2", -no_bound, no_bound},
|
||||
{"p3", 1e-12, no_bound},
|
||||
{"p4", -no_bound, no_bound},
|
||||
{"p5", -no_bound, no_bound},
|
||||
{"mu", -no_bound, no_bound},
|
||||
{"sigma", 1e-12, no_bound},
|
||||
{"A", -no_bound, no_bound},
|
||||
{"C", -no_bound, no_bound},
|
||||
}};
|
||||
|
||||
static double eval(double x, const std::vector<double>& par) {
|
||||
static double eval(double x, const std::vector<double> &par) {
|
||||
const double p0 = par[0];
|
||||
const double p1 = par[1];
|
||||
const double p2 = par[2];
|
||||
@@ -528,16 +541,13 @@ struct FallingScurve {
|
||||
const double p4 = par[4];
|
||||
const double p5 = par[5];
|
||||
|
||||
const double dx = x - p2;
|
||||
const double step = 0.5 * (1.0 - std::erf(dx * inv_sqrt2 / p3));
|
||||
const double dx = x - p2;
|
||||
const double step = 0.5 * (1.0 - fast_erf(dx * inv_sqrt2 / p3));
|
||||
return (p0 + p1 * x) + step * (p4 + p5 * dx);
|
||||
}
|
||||
|
||||
static void eval_and_grad(double x,
|
||||
const std::vector<double>& par,
|
||||
double& f,
|
||||
std::array<double, npar>& g)
|
||||
{
|
||||
static void eval_and_grad(double x, const std::vector<double> &par,
|
||||
double &f, std::array<double, npar> &g) {
|
||||
const double p0 = par[0];
|
||||
const double p1 = par[1];
|
||||
const double p2 = par[2];
|
||||
@@ -545,15 +555,15 @@ struct FallingScurve {
|
||||
const double p4 = par[4];
|
||||
const double p5 = par[5];
|
||||
|
||||
const double dx = x - p2;
|
||||
const double z = dx * inv_sqrt2 / p3;
|
||||
const double step = 0.5 * (1.0 - std::erf(z));
|
||||
const double amp = p4 + p5 * dx;
|
||||
const double dx = x - p2;
|
||||
const double z = dx * inv_sqrt2 / p3;
|
||||
const double step = 0.5 * (1.0 - fast_erf(z));
|
||||
const double amp = p4 + p5 * dx;
|
||||
|
||||
f = (p0 + p1 * x) + step * amp;
|
||||
|
||||
const double e = std::exp(-z * z);
|
||||
const double dSdp2 = +inv_sqrt_2pi * e / p3; // sign flipped vs rising
|
||||
const double e = std::exp(-z * z);
|
||||
const double dSdp2 = +inv_sqrt_2pi * e / p3; // sign flipped vs rising
|
||||
const double dSdp3 = +inv_sqrt_2pi * e * dx / (p3 * p3);
|
||||
|
||||
g[0] = 1.0;
|
||||
@@ -565,29 +575,28 @@ struct FallingScurve {
|
||||
}
|
||||
|
||||
/** @brief Reject degenerate width (zero transition width). */
|
||||
static bool is_valid(const std::vector<double>& par) {
|
||||
static bool is_valid(const std::vector<double> &par) {
|
||||
return par[3] != 0.0;
|
||||
}
|
||||
|
||||
/** @brief Data-driven initial parameter estimates for a falling S-curve. */
|
||||
static std::array<double, npar> estimate_par(NDView<double, 1> x,
|
||||
NDView<double, 1> y)
|
||||
{
|
||||
NDView<double, 1> y) {
|
||||
const ssize_t n = y.size();
|
||||
|
||||
// baseline: last ~10% of points (after turn-off)
|
||||
ssize_t n_base = std::max<ssize_t>(n / 10, 2);
|
||||
double sum_y = 0, sum_xy = 0, sum_x = 0, sum_x2 = 0;
|
||||
for (ssize_t i = n - n_base; i < n; ++i) {
|
||||
sum_y += y[i];
|
||||
sum_x += x[i];
|
||||
sum_y += y[i];
|
||||
sum_x += x[i];
|
||||
sum_xy += x[i] * y[i];
|
||||
sum_x2 += x[i] * x[i];
|
||||
}
|
||||
double denom = n_base * sum_x2 - sum_x * sum_x;
|
||||
double p1 = (std::abs(denom) > 1e-30)
|
||||
? (n_base * sum_xy - sum_x * sum_y) / denom
|
||||
: 0.0;
|
||||
? (n_base * sum_xy - sum_x * sum_y) / denom
|
||||
: 0.0;
|
||||
double p0 = (sum_y - p1 * sum_x) / n_base;
|
||||
|
||||
// plateau: average of first ~10%
|
||||
@@ -617,10 +626,16 @@ struct FallingScurve {
|
||||
double y_10 = baseline_at_mid + 0.1 * p4;
|
||||
double x_90 = x[0], x_10 = x[n - 1];
|
||||
for (ssize_t i = 0; i < n; ++i) {
|
||||
if (y[i] <= y_90) { x_90 = x[i]; break; }
|
||||
if (y[i] <= y_90) {
|
||||
x_90 = x[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (ssize_t i = 0; i < n; ++i) {
|
||||
if (y[i] <= y_10) { x_10 = x[i]; break; }
|
||||
if (y[i] <= y_10) {
|
||||
x_10 = x[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// same CDF relationship: 10%-90% width = 2 * 1.2816 * sigma
|
||||
double p3 = std::max((x_10 - x_90) / 2.5631, 1.0);
|
||||
@@ -629,12 +644,13 @@ struct FallingScurve {
|
||||
|
||||
return {p0, p1, p2, p3, p4, p5};
|
||||
}
|
||||
|
||||
static void compute_steps(const std::array<double, npar>& start,
|
||||
double x_range, double y_range, double slope_scale,
|
||||
std::array<double, npar>& steps)
|
||||
{
|
||||
RisingScurve::compute_steps(start, x_range, y_range, slope_scale, steps);
|
||||
|
||||
static void compute_steps(const std::array<double, npar> &start,
|
||||
double x_range, double y_range,
|
||||
double slope_scale,
|
||||
std::array<double, npar> &steps) {
|
||||
RisingScurve::compute_steps(start, x_range, y_range, slope_scale,
|
||||
steps);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ class NDArray : public ArrayExpr<NDArray<T, Ndim>, Ndim> {
|
||||
* @brief Default constructor. Constructs an empty NDArray.
|
||||
*
|
||||
*/
|
||||
NDArray() : shape_(), strides_(c_strides<Ndim>(shape_)), data_(nullptr){};
|
||||
NDArray() : shape_(), strides_(c_strides<Ndim>(shape_)), data_(nullptr) {};
|
||||
|
||||
/**
|
||||
* @brief Construct a new NDArray object with a given shape.
|
||||
|
||||
@@ -63,7 +63,7 @@ template <class T> struct ProducerConsumerQueue {
|
||||
return *this;
|
||||
}
|
||||
|
||||
ProducerConsumerQueue() : ProducerConsumerQueue(2){};
|
||||
ProducerConsumerQueue() : ProducerConsumerQueue(2) {};
|
||||
// size must be >= 2.
|
||||
//
|
||||
// Also, note that the number of usable slots in the queue at any
|
||||
|
||||
@@ -67,7 +67,7 @@ class Logger {
|
||||
|
||||
public:
|
||||
Logger() = default;
|
||||
explicit Logger(TLogLevel level) : m_level(level){};
|
||||
explicit Logger(TLogLevel level) : m_level(level) {};
|
||||
~Logger() {
|
||||
// output in the destructor to allow for << syntax
|
||||
os << RESET << '\n';
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
#pragma once
|
||||
#include "aare/NDView.hpp"
|
||||
#include "aare/utils/task.hpp"
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "aare/NDView.hpp"
|
||||
#include "aare/utils/task.hpp"
|
||||
|
||||
namespace aare {
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 4e72289..33dd58a 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -4,7 +4,7 @@
|
||||
# For the licensing terms see $ROOTSYS/LICENSE.
|
||||
# For the list of contributors see $ROOTSYS/README/CREDITS.
|
||||
|
||||
-cmake_minimum_required(VERSION 3.1)
|
||||
+cmake_minimum_required(VERSION 3.15)
|
||||
|
||||
if(NOT CMAKE_PROJECT_NAME STREQUAL ROOT)
|
||||
project(Minuit2 LANGUAGES CXX)
|
||||
diff --git a/StandAlone.cmake b/StandAlone.cmake
|
||||
index 0a662ba..b7a05ca 100644
|
||||
--- a/StandAlone.cmake
|
||||
+++ b/StandAlone.cmake
|
||||
@@ -1,12 +1,12 @@
|
||||
-cmake_minimum_required(VERSION 3.1)
|
||||
-
|
||||
-# Tested with and supporting policies up to the following CMake version.
|
||||
-# Not using ... syntax due to parser bug in MSVC's built-in CMake server mode.
|
||||
-if(${CMAKE_VERSION} VERSION_LESS 3.12)
|
||||
- cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
|
||||
-else()
|
||||
- cmake_policy(VERSION 3.12)
|
||||
-endif()
|
||||
+cmake_minimum_required(VERSION 3.15)
|
||||
+
|
||||
+# # Tested with and supporting policies up to the following CMake version.
|
||||
+# # Not using ... syntax due to parser bug in MSVC's built-in CMake server mode.
|
||||
+# if(${CMAKE_VERSION} VERSION_LESS 3.12)
|
||||
+# cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
|
||||
+# else()
|
||||
+# cmake_policy(VERSION 3.12)
|
||||
+# endif()
|
||||
|
||||
include(FeatureSummary)
|
||||
include(CMakeDependentOption)
|
||||
+1
-1
@@ -41,4 +41,4 @@ AARE_INSTALL_PYTHONEXT = "ON"
|
||||
[tool.pytest.ini_options]
|
||||
markers = [
|
||||
"files: marks tests that need additional data (deselect with '-m \"not files\"')",
|
||||
]
|
||||
]
|
||||
+20
-26
@@ -1,18 +1,20 @@
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
find_package (Python 3.10 COMPONENTS Interpreter Development.Module REQUIRED)
|
||||
find_package(
|
||||
Python 3.10
|
||||
COMPONENTS Interpreter Development.Module
|
||||
REQUIRED)
|
||||
set(PYBIND11_FINDPYTHON ON) # Needed for RH8
|
||||
|
||||
# Download or find pybind11 depending on configuration
|
||||
if(AARE_FETCH_PYBIND11)
|
||||
FetchContent_Declare(
|
||||
pybind11
|
||||
GIT_REPOSITORY https://github.com/pybind/pybind11
|
||||
GIT_TAG v2.13.6
|
||||
)
|
||||
FetchContent_MakeAvailable(pybind11)
|
||||
FetchContent_Declare(
|
||||
pybind11
|
||||
GIT_REPOSITORY https://github.com/pybind/pybind11
|
||||
GIT_TAG v3.0.3)
|
||||
FetchContent_MakeAvailable(pybind11)
|
||||
else()
|
||||
find_package(pybind11 2.13 REQUIRED)
|
||||
find_package(pybind11 3.0.3 REQUIRED)
|
||||
endif()
|
||||
|
||||
# ---- Main CPU module --------------------------------------------------------
|
||||
@@ -25,10 +27,9 @@ endif()
|
||||
pybind11_add_module(_aare NO_EXTRAS src/module.cpp)
|
||||
|
||||
target_link_libraries(_aare PRIVATE aare_core aare_compiler_flags)
|
||||
|
||||
target_include_directories(_aare SYSTEM PRIVATE
|
||||
$<TARGET_PROPERTY:Minuit2::Minuit2,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
target_include_directories(
|
||||
_aare SYSTEM
|
||||
PRIVATE $<TARGET_PROPERTY:Minuit2::Minuit2,INTERFACE_INCLUDE_DIRECTORIES>)
|
||||
|
||||
set_target_properties(_aare PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/aare
|
||||
@@ -61,7 +62,7 @@ if(AARE_CUDA)
|
||||
endif()
|
||||
|
||||
# List of python files to be copied to the build directory
|
||||
set( PYTHON_FILES
|
||||
set(PYTHON_FILES
|
||||
aare/__init__.py
|
||||
aare/CtbRawFile.py
|
||||
aare/ClusterFinder.py
|
||||
@@ -72,32 +73,25 @@ set( PYTHON_FILES
|
||||
aare/RawFile.py
|
||||
aare/transform.py
|
||||
aare/ScanParameters.py
|
||||
aare/utils.py
|
||||
)
|
||||
|
||||
aare/utils.py)
|
||||
|
||||
# Copy the python files to the build directory
|
||||
foreach(FILE ${PYTHON_FILES})
|
||||
configure_file(${FILE} ${CMAKE_BINARY_DIR}/${FILE} )
|
||||
configure_file(${FILE} ${CMAKE_BINARY_DIR}/${FILE})
|
||||
endforeach(FILE ${PYTHON_FILES})
|
||||
|
||||
# set_target_properties(_aare PROPERTIES
|
||||
# LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/aare
|
||||
# )
|
||||
|
||||
set(PYTHON_EXAMPLES
|
||||
examples/play.py
|
||||
examples/fits.py
|
||||
)
|
||||
|
||||
set(PYTHON_EXAMPLES examples/play.py examples/fits.py)
|
||||
|
||||
# Copy the python examples to the build directory
|
||||
foreach(FILE ${PYTHON_EXAMPLES})
|
||||
configure_file(${FILE} ${CMAKE_BINARY_DIR}/${FILE} )
|
||||
message(STATUS "Copying ${FILE} to ${CMAKE_BINARY_DIR}/${FILE}")
|
||||
configure_file(${FILE} ${CMAKE_BINARY_DIR}/${FILE})
|
||||
message(STATUS "Copying ${FILE} to ${CMAKE_BINARY_DIR}/${FILE}")
|
||||
endforeach(FILE ${PYTHON_EXAMPLES})
|
||||
|
||||
|
||||
if(AARE_INSTALL_PYTHONEXT)
|
||||
set(AARE_PY_INSTALL_TARGETS _aare)
|
||||
if(AARE_CUDA)
|
||||
@@ -116,4 +110,4 @@ if(AARE_INSTALL_PYTHONEXT)
|
||||
DESTINATION aare
|
||||
COMPONENT python
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
@@ -35,6 +35,22 @@ void define_ClusterVector(py::module &m, const std::string &typestr) {
|
||||
|
||||
.def(py::init()) // TODO change!!!
|
||||
|
||||
.def(
|
||||
"__call__",
|
||||
[](ClusterVector<ClusterType> &self, py::array_t<bool> mask) {
|
||||
return self(make_view_1d(mask));
|
||||
},
|
||||
py::arg("mask"), R"(
|
||||
Create a copy of the clustervector and apply a boolean mask to the ClusterVector.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
mask : 1d boolean numpy array
|
||||
Mask to apply to the ClusterVector. Must be the same length as the number of clusters in the ClusterVector.
|
||||
|
||||
)")
|
||||
|
||||
.def("push_back",
|
||||
[](ClusterVector<ClusterType> &self, const ClusterType &cluster) {
|
||||
self.push_back(cluster);
|
||||
|
||||
+135
-107
@@ -5,64 +5,88 @@
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/stl_bind.h>
|
||||
|
||||
#include "aare/Chi2.hpp"
|
||||
#include "aare/Fit.hpp"
|
||||
#include "aare/FitModel.hpp"
|
||||
#include "aare/Models.hpp"
|
||||
#include "aare/Chi2.hpp"
|
||||
|
||||
namespace py = pybind11;
|
||||
using namespace pybind11::literals;
|
||||
|
||||
template <typename Model, typename FCN>
|
||||
py::object fit_dispatch(
|
||||
const aare::FitModel<Model>& model,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> x,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> y,
|
||||
py::object y_err_obj,
|
||||
int n_threads);
|
||||
py::object
|
||||
fit_dispatch(const aare::FitModel<Model> &model,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> x,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> y,
|
||||
py::object y_err_obj, int n_threads);
|
||||
|
||||
template <typename Model>
|
||||
void bind_fit_model(py::module& m, const char* name) {
|
||||
template <typename Model> void bind_fit_model(py::module &m, const char *name) {
|
||||
using FM = aare::FitModel<Model>;
|
||||
using FCN = aare::func::Chi2Model1DGrad<Model>;
|
||||
py::class_<FM>(m, name)
|
||||
.def(py::init<unsigned int, unsigned int, double, bool>(),
|
||||
py::arg("strategy") = 0,
|
||||
py::arg("max_calls") = 100,
|
||||
py::arg("tolerance") = 0.5,
|
||||
py::arg("compute_errors") = false)
|
||||
.def("SetParLimits", &FM::SetParLimits, py::arg("idx"), py::arg("lo"), py::arg("hi"))
|
||||
.def("FixParameter", &FM::FixParameter, py::arg("idx"), py::arg("val"))
|
||||
.def("ReleaseParameter", &FM::ReleaseParameter, py::arg("idx"))
|
||||
.def("SetParameter", &FM::SetParameter, py::arg("idx"), py::arg("val"))
|
||||
py::arg("strategy") = 0, py::arg("max_calls") = 100,
|
||||
py::arg("tolerance") = 0.5, py::arg("compute_errors") = false)
|
||||
.def("SetParLimits",
|
||||
py::overload_cast<unsigned int, double, double>(&FM::SetParLimits),
|
||||
py::arg("idx"), py::arg("lo"), py::arg("hi"))
|
||||
.def("SetParLimits",
|
||||
py::overload_cast<const std::string &, double, double>(
|
||||
&FM::SetParLimits),
|
||||
py::arg("idx"), py::arg("lo"), py::arg("hi"))
|
||||
.def("FixParameter",
|
||||
py::overload_cast<unsigned int, double>(&FM::FixParameter),
|
||||
py::arg("idx"), py::arg("val"))
|
||||
.def("FixParameter",
|
||||
py::overload_cast<const std::string &, double>(&FM::FixParameter),
|
||||
py::arg("idx"), py::arg("val"))
|
||||
.def("ReleaseParameter",
|
||||
py::overload_cast<unsigned int>(&FM::ReleaseParameter),
|
||||
py::arg("idx"))
|
||||
.def("ReleaseParameter",
|
||||
py::overload_cast<const std::string &>(&FM::ReleaseParameter),
|
||||
py::arg("idx"))
|
||||
.def("SetParameter",
|
||||
py::overload_cast<unsigned int, double>(&FM::SetParameter),
|
||||
py::arg("idx"), py::arg("val"))
|
||||
.def("SetParameter",
|
||||
py::overload_cast<const std::string &, double>(&FM::SetParameter),
|
||||
py::arg("idx"), py::arg("val"))
|
||||
.def("GetParName", &FM::GetParName, py::arg("idx"))
|
||||
.def("GetParNames", &FM::GetParNames)
|
||||
.def_property_readonly("par_names", &FM::GetParNames)
|
||||
.def_property_readonly("n_par",
|
||||
[](py::object /*cls*/) { return Model::npar; })
|
||||
.def_property("max_calls", &FM::max_calls, &FM::SetMaxCalls)
|
||||
.def_property("tolerance", &FM::tolerance, &FM::SetTolerance)
|
||||
.def_property("compute_errors", &FM::compute_errors, &FM::SetComputeErrors)
|
||||
.def("__call__",
|
||||
[](const FM& /*self*/,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> x,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> par)
|
||||
{
|
||||
.def_property("compute_errors", &FM::compute_errors,
|
||||
&FM::SetComputeErrors)
|
||||
.def(
|
||||
"__call__",
|
||||
[](const FM & /*self*/,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> x,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast>
|
||||
par) {
|
||||
auto x_view = make_view_1d(x);
|
||||
auto p_view = make_view_1d(par);
|
||||
|
||||
std::vector<double> pvec(p_view.begin(), p_view.end());
|
||||
|
||||
auto* result = new aare::NDArray<double, 1>({x_view.size()});
|
||||
auto *result = new aare::NDArray<double, 1>({x_view.size()});
|
||||
for (ssize_t i = 0; i < x_view.size(); ++i)
|
||||
(*result)(i) = Model::eval(x_view[i], pvec);
|
||||
|
||||
return return_image_data(result);
|
||||
},
|
||||
py::arg("x"), py::arg("par"))
|
||||
.def("fit",
|
||||
[](const FM& self,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> x,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> y,
|
||||
py::object y_err_obj,
|
||||
int n_threads) -> py::object
|
||||
{
|
||||
return fit_dispatch<Model, FCN>(self, x, y, y_err_obj, n_threads);
|
||||
.def(
|
||||
"fit",
|
||||
[](const FM &self,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> x,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> y,
|
||||
py::object y_err_obj, int n_threads) -> py::object {
|
||||
return fit_dispatch<Model, FCN>(self, x, y, y_err_obj,
|
||||
n_threads);
|
||||
},
|
||||
R"doc(
|
||||
Fit this model to 1D or 3D data using Minuit2.
|
||||
@@ -78,24 +102,21 @@ void bind_fit_model(py::module& m, const char* name) {
|
||||
n_threads : int
|
||||
Number of threads for 3D parallel loop.
|
||||
)doc",
|
||||
py::arg("x"),
|
||||
py::arg("y"),
|
||||
py::arg("y_err") = py::none(),
|
||||
py::arg("x"), py::arg("y"), py::arg("y_err") = py::none(),
|
||||
py::arg("n_threads") = 4);
|
||||
}
|
||||
|
||||
template <typename Model>
|
||||
py::dict pack_1d_result_dict(const aare::NDArray<double, 1>& result,
|
||||
bool compute_errors)
|
||||
{
|
||||
py::dict pack_1d_result_dict(const aare::NDArray<double, 1> &result,
|
||||
bool compute_errors) {
|
||||
constexpr std::size_t npar = Model::npar;
|
||||
|
||||
auto res = result.view();
|
||||
|
||||
auto par_out = new NDArray<double, 1>({npar}, 0.0);
|
||||
auto chi2_out = new NDArray<double, 1>({1}, 0.0);
|
||||
auto par_out = new NDArray<double, 1>({npar}, 0.0);
|
||||
auto chi2_out = new NDArray<double, 1>({1}, 0.0);
|
||||
|
||||
auto par_view = par_out->view();
|
||||
auto par_view = par_out->view();
|
||||
auto chi2_view = chi2_out->view();
|
||||
|
||||
for (std::size_t i = 0; i < npar; ++i) {
|
||||
@@ -103,7 +124,7 @@ py::dict pack_1d_result_dict(const aare::NDArray<double, 1>& result,
|
||||
}
|
||||
|
||||
if (compute_errors) {
|
||||
auto err_out = new NDArray<double, 1>({npar}, 0.0);
|
||||
auto err_out = new NDArray<double, 1>({npar}, 0.0);
|
||||
auto err_view = err_out->view();
|
||||
|
||||
for (std::size_t i = 0; i < npar; ++i) {
|
||||
@@ -112,58 +133,59 @@ py::dict pack_1d_result_dict(const aare::NDArray<double, 1>& result,
|
||||
|
||||
chi2_view(0) = res(2 * npar);
|
||||
|
||||
return py::dict(
|
||||
"par"_a = return_image_data(par_out),
|
||||
"par_err"_a = return_image_data(err_out),
|
||||
"chi2"_a = return_image_data(chi2_out));
|
||||
return py::dict("par"_a = return_image_data(par_out),
|
||||
"par_err"_a = return_image_data(err_out),
|
||||
"chi2"_a = return_image_data(chi2_out));
|
||||
} else {
|
||||
chi2_view(0) = res(npar);
|
||||
|
||||
return py::dict(
|
||||
"par"_a = return_image_data(par_out),
|
||||
"chi2"_a = return_image_data(chi2_out));
|
||||
return py::dict("par"_a = return_image_data(par_out),
|
||||
"chi2"_a = return_image_data(chi2_out));
|
||||
}
|
||||
}
|
||||
|
||||
// Helper: typed dispatch for one Model, handles 1D/3D + y_err logic
|
||||
template <typename Model, typename FCN>
|
||||
py::object fit_dispatch(
|
||||
const aare::FitModel<Model>& model,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> x,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> y,
|
||||
py::object y_err_obj,
|
||||
int n_threads)
|
||||
{
|
||||
py::object
|
||||
fit_dispatch(const aare::FitModel<Model> &model,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> x,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> y,
|
||||
py::object y_err_obj, int n_threads) {
|
||||
constexpr std::size_t npar = Model::npar;
|
||||
|
||||
if (y.ndim() == 3) {
|
||||
auto par_out = new NDArray<double, 3>({y.shape(0), y.shape(1), npar}, 0.0);
|
||||
auto chi2_out= new NDArray<double, 2>({y.shape(0), y.shape(1)}, 0.0);
|
||||
auto par_out =
|
||||
new NDArray<double, 3>({y.shape(0), y.shape(1), npar}, 0.0);
|
||||
auto chi2_out = new NDArray<double, 2>({y.shape(0), y.shape(1)}, 0.0);
|
||||
|
||||
auto x_view = make_view_1d(x);
|
||||
auto y_view = make_view_3d(y);
|
||||
|
||||
if (!y_err_obj.is_none()) {
|
||||
auto y_err = py::cast<py::array_t<double,
|
||||
py::array::c_style | py::array::forcecast>>(y_err_obj);
|
||||
auto y_err = py::cast<
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast>>(
|
||||
y_err_obj);
|
||||
|
||||
if (y_err.ndim() != 3) {
|
||||
throw std::runtime_error("For 3D input y, y_err must also be 3D.");
|
||||
throw std::runtime_error(
|
||||
"For 3D input y, y_err must also be 3D.");
|
||||
}
|
||||
|
||||
auto err_out = new NDArray<double, 3>({y.shape(0), y.shape(1), npar}, 0.0);
|
||||
|
||||
auto err_out =
|
||||
new NDArray<double, 3>({y.shape(0), y.shape(1), npar}, 0.0);
|
||||
auto y_view_err = make_view_3d(y_err);
|
||||
|
||||
aare::fit_3d<Model, FCN>(model, x_view, y_view, y_view_err,
|
||||
par_out->view(), err_out->view(), chi2_out->view(), n_threads);
|
||||
|
||||
aare::fit_3d<Model, FCN>(model, x_view, y_view, y_view_err,
|
||||
par_out->view(), err_out->view(),
|
||||
chi2_out->view(), n_threads);
|
||||
|
||||
if (model.compute_errors()) {
|
||||
return py::dict("par"_a = return_image_data(par_out),
|
||||
return py::dict("par"_a = return_image_data(par_out),
|
||||
"par_err"_a = return_image_data(err_out),
|
||||
"chi2"_a = return_image_data(chi2_out));
|
||||
"chi2"_a = return_image_data(chi2_out));
|
||||
} else {
|
||||
delete err_out;
|
||||
return py::dict("par"_a = return_image_data(par_out),
|
||||
return py::dict("par"_a = return_image_data(par_out),
|
||||
"chi2"_a = return_image_data(chi2_out));
|
||||
}
|
||||
} else {
|
||||
@@ -171,9 +193,10 @@ py::object fit_dispatch(
|
||||
NDView<double, 3> dummy_err{};
|
||||
NDView<double, 3> dummy_err_out{};
|
||||
|
||||
aare::fit_3d<Model, FCN>(model, x_view, y_view, dummy_err,
|
||||
par_out->view(), dummy_err_out, chi2_out->view(), n_threads);
|
||||
|
||||
aare::fit_3d<Model, FCN>(model, x_view, y_view, dummy_err,
|
||||
par_out->view(), dummy_err_out,
|
||||
chi2_out->view(), n_threads);
|
||||
|
||||
return py::dict("par"_a = return_image_data(par_out),
|
||||
"chi2"_a = return_image_data(chi2_out));
|
||||
}
|
||||
@@ -184,15 +207,18 @@ py::object fit_dispatch(
|
||||
auto y_view = make_view_1d(y);
|
||||
|
||||
if (!y_err_obj.is_none()) {
|
||||
auto y_err = py::cast<py::array_t<double,
|
||||
py::array::c_style | py::array::forcecast>>(y_err_obj);
|
||||
auto y_err = py::cast<
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast>>(
|
||||
y_err_obj);
|
||||
|
||||
if (y_err.ndim() != 1) {
|
||||
throw std::runtime_error("For 1D input y, y_err must also be 1D.");
|
||||
throw std::runtime_error(
|
||||
"For 1D input y, y_err must also be 1D.");
|
||||
}
|
||||
|
||||
auto y_view_err = make_view_1d(y_err);
|
||||
result = aare::fit_pixel<Model, FCN>(model, x_view, y_view, y_view_err);
|
||||
result =
|
||||
aare::fit_pixel<Model, FCN>(model, x_view, y_view, y_view_err);
|
||||
} else {
|
||||
result = aare::fit_pixel<Model, FCN>(model, x_view, y_view);
|
||||
}
|
||||
@@ -395,7 +421,6 @@ void define_fit_bindings(py::module &m) {
|
||||
)",
|
||||
py::arg("x"), py::arg("y"), py::arg("y_err"), py::arg("n_threads") = 4);
|
||||
|
||||
|
||||
m.def(
|
||||
"fit_pol1",
|
||||
[](py::array_t<double, py::array::c_style | py::array::forcecast> x,
|
||||
@@ -567,7 +592,6 @@ void define_fit_bindings(py::module &m) {
|
||||
)",
|
||||
py::arg("x"), py::arg("y"), py::arg("y_err"), py::arg("n_threads") = 4);
|
||||
|
||||
|
||||
m.def(
|
||||
"fit_scurve2",
|
||||
[](py::array_t<double, py::array::c_style | py::array::forcecast> x,
|
||||
@@ -653,7 +677,6 @@ void define_fit_bindings(py::module &m) {
|
||||
)",
|
||||
py::arg("x"), py::arg("y"), py::arg("y_err"), py::arg("n_threads") = 4);
|
||||
|
||||
|
||||
// ── Bind model classes ──────────────────────────────────────────
|
||||
bind_fit_model<aare::model::Gaussian>(m, "Gaussian");
|
||||
bind_fit_model<aare::model::RisingScurve>(m, "RisingScurve");
|
||||
@@ -661,48 +684,57 @@ void define_fit_bindings(py::module &m) {
|
||||
bind_fit_model<aare::model::Pol1>(m, "Pol1");
|
||||
bind_fit_model<aare::model::Pol2>(m, "Pol2");
|
||||
|
||||
m.def("fit",
|
||||
m.def(
|
||||
"fit",
|
||||
[](py::object model_obj,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> x,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast> y,
|
||||
py::object y_err_obj,
|
||||
int n_threads) -> py::object
|
||||
{
|
||||
py::object y_err_obj, int n_threads) -> py::object {
|
||||
using namespace aare::model;
|
||||
using namespace aare::func;
|
||||
|
||||
|
||||
// ── Polynomial of degree 1 ───────
|
||||
if(py::isinstance< aare::FitModel<Pol1> >(model_obj)) {
|
||||
const auto& mdl = model_obj.cast< const aare::FitModel<Pol1>& >();
|
||||
return fit_dispatch<Pol1, Chi2Pol1>(mdl, x, y, y_err_obj, n_threads);
|
||||
if (py::isinstance<aare::FitModel<Pol1>>(model_obj)) {
|
||||
const auto &mdl =
|
||||
model_obj.cast<const aare::FitModel<Pol1> &>();
|
||||
return fit_dispatch<Pol1, Chi2Pol1>(mdl, x, y, y_err_obj,
|
||||
n_threads);
|
||||
}
|
||||
|
||||
// ── Polynomial of degree 2 ───────
|
||||
if(py::isinstance< aare::FitModel<Pol2> >(model_obj)) {
|
||||
const auto& mdl = model_obj.cast< const aare::FitModel<Pol2>& >();
|
||||
return fit_dispatch<Pol2, Chi2Pol2>(mdl, x, y, y_err_obj, n_threads);
|
||||
if (py::isinstance<aare::FitModel<Pol2>>(model_obj)) {
|
||||
const auto &mdl =
|
||||
model_obj.cast<const aare::FitModel<Pol2> &>();
|
||||
return fit_dispatch<Pol2, Chi2Pol2>(mdl, x, y, y_err_obj,
|
||||
n_threads);
|
||||
}
|
||||
// ── Gaussian ───────
|
||||
if(py::isinstance< aare::FitModel<Gaussian> >(model_obj)) {
|
||||
const auto& mdl = model_obj.cast< const aare::FitModel<Gaussian>& >();
|
||||
return fit_dispatch<Gaussian, Chi2Gaussian>(mdl, x, y, y_err_obj, n_threads);
|
||||
if (py::isinstance<aare::FitModel<Gaussian>>(model_obj)) {
|
||||
const auto &mdl =
|
||||
model_obj.cast<const aare::FitModel<Gaussian> &>();
|
||||
return fit_dispatch<Gaussian, Chi2Gaussian>(
|
||||
mdl, x, y, y_err_obj, n_threads);
|
||||
}
|
||||
|
||||
// ── Rising Scurve ───────
|
||||
if(py::isinstance< aare::FitModel<RisingScurve> >(model_obj)) {
|
||||
const auto& mdl = model_obj.cast< const aare::FitModel<RisingScurve>& >();
|
||||
return fit_dispatch<RisingScurve, Chi2RisingScurve>(mdl, x, y, y_err_obj, n_threads);
|
||||
if (py::isinstance<aare::FitModel<RisingScurve>>(model_obj)) {
|
||||
const auto &mdl =
|
||||
model_obj.cast<const aare::FitModel<RisingScurve> &>();
|
||||
return fit_dispatch<RisingScurve, Chi2RisingScurve>(
|
||||
mdl, x, y, y_err_obj, n_threads);
|
||||
}
|
||||
|
||||
// ── Falling Scurve ───────
|
||||
if(py::isinstance< aare::FitModel<FallingScurve> >(model_obj)) {
|
||||
const auto& mdl = model_obj.cast< const aare::FitModel<FallingScurve>& >();
|
||||
return fit_dispatch<FallingScurve, Chi2FallingScurve>(mdl, x, y, y_err_obj, n_threads);
|
||||
if (py::isinstance<aare::FitModel<FallingScurve>>(model_obj)) {
|
||||
const auto &mdl =
|
||||
model_obj.cast<const aare::FitModel<FallingScurve> &>();
|
||||
return fit_dispatch<FallingScurve, Chi2FallingScurve>(
|
||||
mdl, x, y, y_err_obj, n_threads);
|
||||
}
|
||||
|
||||
throw std::runtime_error(
|
||||
"Unknown model type. Expected Pol1, Pol2, Gaussian, RisingScurve or FallingScurve."
|
||||
);
|
||||
"Unknown model type. Expected Pol1, Pol2, Gaussian, "
|
||||
"RisingScurve or FallingScurve.");
|
||||
},
|
||||
R"(
|
||||
Fit a model to 1D or 3D data using Minuit2.
|
||||
@@ -733,10 +765,6 @@ void define_fit_bindings(py::module &m) {
|
||||
"par_err" : (rows, cols, npar) parameter errors (if compute_errors).
|
||||
"chi2" : (rows, cols) chi-squared per pixel.
|
||||
)",
|
||||
py::arg("model"),
|
||||
py::arg("x"),
|
||||
py::arg("y"),
|
||||
py::arg("y_err") = py::none(),
|
||||
py::arg("n_threads") = 4
|
||||
);
|
||||
py::arg("model"), py::arg("x"), py::arg("y"),
|
||||
py::arg("y_err") = py::none(), py::arg("n_threads") = 4);
|
||||
}
|
||||
+341
-336
@@ -1,339 +1,344 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "a9463197",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from aare import Interpolator\n",
|
||||
"import numpy as np \n",
|
||||
"import matplotlib.pyplot as plt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7fdc9ff6",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def calculate_rosenblatt_lookup_table(etacube, etabins_x, etabins_y, etabins_e):\n",
|
||||
"\n",
|
||||
" \"\"\" \n",
|
||||
" Rosenblatt transform: \n",
|
||||
" transforms joint probability P_X,Y to uniform probability between [0,1] U\n",
|
||||
" U_0 = F_X(x) = P(x' < x) marginal CDF of X\n",
|
||||
" U_1 = F_Y|X(y|x) = P(y' < y | x) conditional CDF\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
" #marginal CDF for eta_x\n",
|
||||
" pEtaX = etacube.sum(axis=1) # marginal distribution eta_x\n",
|
||||
" CDF_EtaX = np.concatenate([np.zeros(shape=[1, len(etabins_e)]), np.cumsum(pEtaX, axis=0)], axis=0)\n",
|
||||
" CDF_EtaX = CDF_EtaX / CDF_EtaX[-1] #normalize \n",
|
||||
"\n",
|
||||
" # conditional CDF F_Y|X (a CDF in y direction for each etaX bin)\n",
|
||||
" CDF_EtaY_cond = np.cumsum(etacube, axis=1)\n",
|
||||
" np.divide(CDF_EtaY_cond, np.repeat(pEtaX[:, None, :], len(etabins_y), axis=1), out=np.zeros_like(CDF_EtaY_cond, dtype=np.float64), where=np.repeat(pEtaX[:, None, :], len(etabins_y), axis=1)!=0)\n",
|
||||
"\n",
|
||||
" CDF_EtaY_cond = np.concatenate([np.zeros(shape=[len(etabins_x), 1, len(etabins_e)]), CDF_EtaY_cond], axis=1)\n",
|
||||
" #CDF_EtaY_cond = CDF_EtaY_cond / np.where(CDF_EtaY_cond[:,-1:,:] == 0, 1, CDF_EtaY_cond[:,-1:,:]) #normalize\n",
|
||||
"\n",
|
||||
" # calculate (u,v) at the center of each original bin\n",
|
||||
" \"\"\" \n",
|
||||
" Xc_1d = 0.5 * (F_EtaX_edges[:-1] + F_EtaX_edges[1:]) # why the average between two values?\n",
|
||||
" Yc_2d = 0.5 * (F_EtaY_cond_edges[:, :-1] + F_EtaY_cond_edges[:, 1:])\n",
|
||||
"\n",
|
||||
" X_tab = np.repeat(Xc_1d[:, None], nBinY, axis=1) # (nBinX, nBinY)\n",
|
||||
" Y_tab = Yc_2d # (nBinX, nBinY)\n",
|
||||
" \"\"\" \n",
|
||||
" X_tab = np.repeat(CDF_EtaX[:, None, :], etabins_y.shape[0], axis=1) #TODO: actually does not depend on eta_y at all \n",
|
||||
" Y_tab = CDF_EtaY_cond \n",
|
||||
"\n",
|
||||
" print(\"shape X_tab: \", X_tab.shape)\n",
|
||||
" print(\"shape Y_tab: \", Y_tab.shape)\n",
|
||||
"\n",
|
||||
" return X_tab, Y_tab\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "616d04d7",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Text(0, 0.5, 'y')"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
"cells":
|
||||
[
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "a9463197",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from aare import Interpolator\n",
|
||||
"import numpy as np \n",
|
||||
"import matplotlib.pyplot as plt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "7fdc9ff6",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def calculate_rosenblatt_lookup_table(etacube, etabins_x, etabins_y, etabins_e):\n",
|
||||
"\n",
|
||||
" \"\"\" \n",
|
||||
" Rosenblatt transform: \n",
|
||||
" transforms joint probability P_X,Y to uniform probability between [0,1] U\n",
|
||||
" U_0 = F_X(x) = P(x' < x) marginal CDF of X\n",
|
||||
" U_1 = F_Y|X(y|x) = P(y' < y | x) conditional CDF\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
" #marginal CDF for eta_x\n",
|
||||
" pEtaX = etacube.sum(axis=1) # marginal distribution eta_x\n",
|
||||
" CDF_EtaX = np.concatenate([np.zeros(shape=[1, len(etabins_e)]), np.cumsum(pEtaX, axis=0)], axis=0)\n",
|
||||
" CDF_EtaX = CDF_EtaX / CDF_EtaX[-1] #normalize \n",
|
||||
"\n",
|
||||
" # conditional CDF F_Y|X (a CDF in y direction for each etaX bin)\n",
|
||||
" CDF_EtaY_cond = np.cumsum(etacube, axis=1)\n",
|
||||
" np.divide(CDF_EtaY_cond, np.repeat(pEtaX[:, None, :], len(etabins_y), axis=1), out=np.zeros_like(CDF_EtaY_cond, dtype=np.float64), where=np.repeat(pEtaX[:, None, :], len(etabins_y), axis=1)!=0)\n",
|
||||
"\n",
|
||||
" CDF_EtaY_cond = np.concatenate([np.zeros(shape=[len(etabins_x), 1, len(etabins_e)]), CDF_EtaY_cond], axis=1)\n",
|
||||
" #CDF_EtaY_cond = CDF_EtaY_cond / np.where(CDF_EtaY_cond[:,-1:,:] == 0, 1, CDF_EtaY_cond[:,-1:,:]) #normalize\n",
|
||||
"\n",
|
||||
" # calculate (u,v) at the center of each original bin\n",
|
||||
" \"\"\" \n",
|
||||
" Xc_1d = 0.5 * (F_EtaX_edges[:-1] + F_EtaX_edges[1:]) # why the average between two values?\n",
|
||||
" Yc_2d = 0.5 * (F_EtaY_cond_edges[:, :-1] + F_EtaY_cond_edges[:, 1:])\n",
|
||||
"\n",
|
||||
" X_tab = np.repeat(Xc_1d[:, None], nBinY, axis=1) # (nBinX, nBinY)\n",
|
||||
" Y_tab = Yc_2d # (nBinX, nBinY)\n",
|
||||
" \"\"\" \n",
|
||||
" X_tab = np.repeat(CDF_EtaX[:, None, :], etabins_y.shape[0], axis=1) #TODO: actually does not depend on eta_y at all \n",
|
||||
" Y_tab = CDF_EtaY_cond \n",
|
||||
"\n",
|
||||
" print(\"shape X_tab: \", X_tab.shape)\n",
|
||||
" print(\"shape Y_tab: \", Y_tab.shape)\n",
|
||||
"\n",
|
||||
" return X_tab, Y_tab\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "616d04d7",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"Text(0, 0.5, 'y')"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png":
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAbwAAAHFCAYAAACJnUzWAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAA6OdJREFUeJzs/Xl4HNWdLo6/rd60tVuyZK1ty4BsGSxkBzExi4kdSJwhJCgEE25IyALkhvGQDOEmM2HyZU2exzMJYZw7iUmYhBACNyE2mYhfFkDEmInCkiDjRXZsLBvb6la35G5JpW5Jvap+f7RO6dTpc6qqW63Nqvd5eISrq+qcOnXqsy8WWZZlmDBhwoQJE+c4CuZ6AiZMmDBhwsRswGR4JkyYMGFiUcBkeCZMmDBhYlHAZHgmTJgwYWJRwGR4JkyYMGFiUcBkeCZMmDBhYlHAZHgmTJgwYWJRwGR4JkyYMGFiUcBkeCZMmDBhYlHAZHgmcsYbb7yBm266CbW1tXA4HKipqcHWrVvx+uuvZ3WfBx98EBaLJac57N27FxaLBXv37s3peqPYvHkzNm/ebOg8i8UCi8WCgoICuFwuNDY24qabbsLu3bsxMTGRcc3KlSvxuc99Lqv5vPbaa3jwwQcxPDyc1XXsWGT9du/endV9tDA2NoYHH3yQ+06efPJJWCwWnDp1Km/jZYNEIoE1a9bg3/7t3+ZkfBpDQ0MoKyvDb37zm7meyuKBbMJEDvi///f/ygUFBfJll10mP/XUU/Krr74q//znP5cvu+wyuaCgQP7P//xPw/fq7e2VX3/99ZzmIUmS/Prrr8uSJOV0vVFs2rRJ3rRpk6Hzzj//fPn111+XX3/9dfnll1+W/+u//ku+7rrrZADyVVddJQ8PD6uu2bdvn9zT05PVfL7zne/IAOR33303q+vYsV555RUZgLxr166s7qOFs2fPygDkBx54IOO3gYEB+fXXX5ej0WjexssGO3bskKuqquRIJDIn47N48MEH5cbGRjkWi831VBYFTIZnImt0dnbKBQUF8kc+8hE5kUiofkskEvJHPvIRuaCgQO7s7NS8z+jo6ExOM6/IhuGtXbuW+9sTTzwhA5A/8YlPTHs+2TK8sbEx7vHZZnhziUQiIdfX18tf//rX53oqCgKBgGyz2eRnnnlmrqeyKGAyPBNZ47rrrpOtVqvc29vL/f3MmTOy1WqVP/KRjyjHHnjgARmA3NXVJd94441yWVmZXFNTo/qNRjQale+55x65urpaLioqkq+66ir5rbfekhsaGuTPfvazynmEYL/yyivKsc9+9rNySUmJfPz4cfnaa6+VS0pKZI/HI99zzz0ZmsWDDz4ov/e975XLy8tll8slv+c975F//OMfyxMTE6rz8sHwZFmWP/zhD8sWi0U+deqUcox9plQqJX/zm9+UV69eLRcWFsput1u++OKL5R07dqjWi/2PrEFDQ4N83XXXyc8995y8fv162el0yv/yL//CHYus389//nP5K1/5ilxdXS0XFhbK73vf++R9+/YZWoPPfvazckNDgyzLsvzuu+9y50bG/OlPf8pl1D/5yU/klpYW2el0yuXl5fLHPvYx+ciRIxnjGH2vPDz33HMyAPnw4cPKsfHxcXn9+vXyBRdcoNK8/X6/XF1dLW/atElOJpO696Zx9dVXy01NTRl7aGJiQr7gggvkD3/4w6rj1157rXzVVVdlNYaJ3GD68ExkhVQqhVdeeQWXXnopPB4P95zly5ejtbUVe/bsQSqVUv328Y9/HI2Njdi1axd++MMfCsf5/Oc/jx07duDzn/882tvbceONN+KGG24w7LNKJBK4/vrrcc0116C9vR233XYb/uM//gP//u//rjrv1KlT+OIXv4hf/epX+PWvf42Pf/zj+NKXvoRvfvObhsbJFtdffz1kWcaf/vQn4Tnf/va38eCDD+KTn/wkfve73+HZZ5/F7bffrjz7HXfcgS996UsAgF//+td4/fXX8frrr+OSSy5R7rFv3z587Wtfw5e//GW88MILuPHGGzXn9a//+q84efIkfvzjH+PHP/4x+vr6sHnzZpw8eTKr56utrcULL7wAALj99tuVud13333Ca7Zv347bb78da9euxa9//Wt873vfw8GDB3H55Zfj+PHjqnONvlcefve736GqqgoXXXSRcqywsBC/+tWvMDAwgNtuuw0AMDExgU996lOQZRm/+MUvYLVas1qDf/qnf8KxY8fwxz/+UXX8D3/4A06cOIF//Md/VB3fvHkz/vznP2ftjzWRA+aa45pYWAgEAjIA+X/9r/+led7NN98sA5D7+/tlWZ7SSu6///6Mc1kN7/DhwzIARSsh+MUvfqHSFmRZrOEBkH/1q1+prv/whz8sNzU1CeecSqXkRCIh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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 640x480 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"## joint conditional distribution \n",
|
||||
"rng = np.random.default_rng(42)\n",
|
||||
"n = 10_000_000 \n",
|
||||
" \n",
|
||||
"## circular distribution x,y dependant \n",
|
||||
"theta = rng.uniform(0, 4*np.pi, size=n)\n",
|
||||
"r = rng.uniform(0.3, 0.4) \n",
|
||||
"#r = 0.3 + 0.4 * (theta / (4*np.pi)) # 螺旋半径从 0.3 到 0.7\n",
|
||||
"x_raw = r * np.cos(theta) + 0.1 * rng.normal(size=n)\n",
|
||||
"y_raw = r * np.sin(theta) + 0.1 * rng.normal(size=n)\n",
|
||||
" \n",
|
||||
"# scale to [0, 1]\n",
|
||||
"x = (x_raw - x_raw.min()) / (x_raw.max() - x_raw.min())\n",
|
||||
"y = (y_raw - y_raw.min()) / (y_raw.max() - y_raw.min())\n",
|
||||
" \n",
|
||||
"plt.scatter(x[:5000], y[:5000], s=1, alpha=0.5)\n",
|
||||
"plt.title(\"Original Distribution (x, y)\")\n",
|
||||
"plt.gca().set_aspect('equal')\n",
|
||||
"plt.xlabel(\"x\")\n",
|
||||
"plt.ylabel(\"y\")\n",
|
||||
" "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "a713be97",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def plot(x, y, CDF_X, CDF_Y, u, v): \n",
|
||||
" #plot\n",
|
||||
" fig, axs = plt.subplots(1, 4, figsize=(15, 4))\n",
|
||||
" \n",
|
||||
" axs[0].scatter(x[:5000], y[:5000], s=1, alpha=0.5)\n",
|
||||
" axs[0].set_title(\"Original (x, y)\")\n",
|
||||
" axs[0].set_aspect('equal')\n",
|
||||
" axs[0].set_xlabel(\"x\")\n",
|
||||
" axs[0].set_ylabel(\"y\")\n",
|
||||
" \n",
|
||||
" axs[1].imshow(CDF_X[:,:,0], origin='lower', extent=[0,1,0,1], cmap='viridis')\n",
|
||||
" axs[1].set_title(\"normalized CDF_X (u = F_X(x))\")\n",
|
||||
" axs[1].set_xlabel(\"y\")\n",
|
||||
" axs[1].set_ylabel(\"P_X(x < x')\")\n",
|
||||
"\n",
|
||||
" axs[2].imshow(CDF_Y[:,:,0], origin='lower', extent=[0,1,0,1], cmap='viridis')\n",
|
||||
" axs[2].set_title(\"normalized conditional CDF_Y (u = F_Y|X(y|x))\")\n",
|
||||
" axs[2].set_xlabel(\"P_Y|X(y < y'|x)\")\n",
|
||||
" axs[2].set_ylabel(\"x\")\n",
|
||||
"\n",
|
||||
" axs[3].scatter(u[:5000], v[:5000], s=1, alpha=0.5, color='blue')\n",
|
||||
" axs[3].set_title(\"Mapped (u, v)\")\n",
|
||||
" axs[3].set_aspect('equal')\n",
|
||||
" axs[3].set_xlim(0,1); axs[2].set_ylim(0,1)\n",
|
||||
" axs[3].set_xlabel(\"u\")\n",
|
||||
" axs[3].set_ylabel(\"v\")\n",
|
||||
" \n",
|
||||
" plt.tight_layout()\n",
|
||||
" plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "0e87346a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"(300, 300, 2)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"#calculate joint probability density function\n",
|
||||
"nBins = 300\n",
|
||||
"range = np.array([[x.min(),x.max()], [y.min(),y.max()]])\n",
|
||||
"bin_width = (range[:,0] - range[:,1])/nBins\n",
|
||||
"H, xedges, yedges = np.histogram2d(x, y, bins=nBins, range=range)\n",
|
||||
"H = H.astype(int) \n",
|
||||
"H = np.repeat(H[:,:,None], 2, axis=2) #add energy axis\n",
|
||||
"\n",
|
||||
"print(H.shape)\n",
|
||||
"ebins = [0,1,2] #dummy energy bins"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "d63e9295",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png":
|
||||
"iVBORw0KGgoAAAANSUhEUgAABdIAAAGWCAYAAAB8cHHOAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzsnXl8FEX6xp/qniMBQlCOEAynCIjiQXBVUAFxdRFZdWXlhxeKuiAKq6yK6CIi66LiwXqAFwqsirpeqHhhBF0UlEMFFkUBOQIJkSskQJKZ6fr9UV093T3dMz2TyQXv188409XV1dXVPT3kqbefl3HOOQiCIAiCIAiCIAiCIAiCIAiCcESp6w4QBEEQBEEQBEEQBEEQBEEQRH2GhHSCIAiCIAiCIAiCIAiCIAiCiAMJ6QRBEARBEARBEARBEARBEAQRBxLSCYIgCIIgCIIgCIIgCIIgCCIOJKQTBEEQBEEQBEEQBEEQBEEQRBxISCcIgiAIgiAIgiAIgiAIgiCIOJCQThAEQRAEQRAEQRAEQRAEQRBxICGdIAiCIAiCIAiCIAiCIAiCIOJAQjpBEARBEARBEARBEARBEARBxIGEdIIgCIIgCIIgCIIgCIKo58yePRuMMTDGsHjx4pj1nHN07twZjDH069ev1vtXU8jj3rx5s6f6I0aMwB/+8Iea7ZRHfv75ZwQCAaxataquu0KkARLSCYIgCIIgCIIgCIIgCKKBkJWVhVmzZsWUf/HFF9i4cSOysrLqoFf1g++++w5z5szBP/7xj7ruCgCgS5cuuPLKK3HbbbfVdVeINEBCOkEQBEEQBEEQBEEQBEE0EIYOHYq33noL+/fvt5TPmjULZ555Jtq1a1dHPat7HnzwQfzud79Dr1696rorBrfccgu+/PJLfP3113XdFaKakJBOEARBEARBEARBEARBEA2EYcOGAQDmzZtnlJWWluKtt97CiBEjHLeZPHkyTj/9dBx99NFo2rQpevbsiVmzZoFzbqnXoUMHXHTRRXjnnXdw0kknISMjA506dcITTzxhqbd48WIwxvDyyy9j3LhxaN26NTIzM9G3b1989913MftfsWIF/vjHP+Loo49GRkYGTj31VLzxxhsx9ZYtW4Y+ffogIyMDbdq0wYQJExAKhTyNy86dO/HOO+/g6quvtpS7WcPIY3CyyYlHKBRCq1atYvYDAPv27UNmZibGjRtnlOXn5+P444/HM888k9R+iPoHCekEQRAEQRAEQRAEQRAE0UBo2rQphgwZghdffNEomzdvHhRFwdChQx232bx5M0aOHIk33ngDb7/9Nv70pz9hzJgxmDJlSkzd77//Hrfeeituu+02vPPOO+jduzf++te/4pFHHompe/fdd2PTpk144YUX8MILL2DHjh3o168fNm3aZNRZtGgR+vTpg3379uGZZ57B/Pnzccopp2Do0KGYPXu2UW/dunUYMGAA9u3bh9mzZ+OZZ57Bd99959mm5dNPP0UoFEL//v091U8Vv9+Pq666yvGpgHnz5qGiogLXXXedpbxfv3746KOPYiYuiIaFr647QBAEQRAEQRAEQRAEQRCEd0aMGIH+/fvjf//7H0444QS8+OKL+POf/+zqj/7SSy8ZnzVNQ79+/cA5x7/+9S9MnDgRjDFj/Y4dO/Ddd9/h5JNPBgAMHDgQJSUlmDJlCkaPHo1GjRoZdVu2bIl33nnH2P6ss87Ccccdh6lTp+L5558HAIwePRonnHACPv/8c/h8Qoq84IILsGvXLtx999245pproCgK7r//fnDO8fnnnyMnJwcAMGjQIJx44omexmTp0qXIzMxEt27dvA5jylx33XV4/PHH8frrr+PGG280ymfPno38/Hz06NHDUr9nz56YOXMm1q9fXyv9I2oGikgnCIIgCIIgCIIgCIIgiAZE3759ceyxx+LFF1/EmjVrsHz5cldbFwD4/PPPcd555yE7OxuqqsLv9+Pee+/F7t27UVJSYql7wgknGCK65IorrsD+/fuxatWqmHKzCN++fXv07t0bixYtAgBs2LABP/30E6688koAQDgcNl4XXnghioqKsH79egAicn3AgAGGiA4Aqqq6Rtnb2bFjB1q2bGnpT03Ro0cP5OfnWyYofvzxR3z77beO56FVq1YAgO3bt9d434iag4R0giAIgiAIgiAIgiAIgmhAMMZw3XXX4eWXX8YzzzyDLl264Oyzz3as++233+L8888HADz//PP46quvsHz5ctxzzz0AgEOHDlnqt27dOqYNWbZ7925PdWW9nTt3AgBuv/12+P1+y2v06NEAgF27dhltx9t3Ig4dOoSMjAxPddPBiBEjsHTpUvz0008ARNR/MBg0POzNyH7Zx5poWJCQThAEQRAEQRAEQRAEQRANjGuvvRa7du3CM888E+PJbea1116D3+/HBx98gMsvvxy9e/dGr169XOsXFxe7ljVv3txTXVmvRYsWAIAJEyZg+fLljq9TTjnFaDvevhPRokUL7NmzJ6ZcitiVlZWWcingp8qwYcMQDAYxe/ZsRCIR/Pvf/8Yll1yCo446Kqau7JccD6JhQkI6QRAEQRAEQRAEQRAEQTQwjjnmGNxxxx0YPHgwhg8f7lqPMQafzwdVVY2yQ4cO4d///rdj/f/973/44YcfLGWvvvoqsrKy0LNnT0v5vHnzLAk0t2zZgq+//hr9+vUDAHTt2hXHHXccfvjhB/Tq1cvxJX3d+/fvj4KCAiOKHQAikQhef/11T+PRrVs37N69G6WlpZbyDh06AABWr15tKX/vvfc8tevGUUcdhUsuuQRz587FBx98gOLiYld7nU2bNkFRFHTt2rVa+yTqFhLSCYIgCIIgCIIgCIIgCKIB8uCDD+Ldd99Fbm6ua51BgwahvLwcV1xxBRYuXIjXXnsNZ599NoLBoGP9Nm3a4I9//CNeeuklfPzxx7jqqquwcOFC/P3vf7ckGgWAkpISXHrppViwYAFeffVVnHfeecjIyMCECROMOs8++ywKCgpwwQUXYN68efjyyy/x7rvvYurUqfjzn/9s1Pv73/8OADj33HPx+uuv4/3338egQYNw4MABT2MhE6h+8803lvLTTjsNXbt2xe2334558+bh448/xsiRI7FkyZKYNhYvXgzGGO677z5P+xwxYgSKiopwyy23IC8vD+edd55jvWXLluGUU05xjFYnGg4kpBMEQRAEQRAEQRAEQRDEYcq5555rJCUdPHgw7rnnHgwZMgR33XWXY/1TTjkFjz32GB599FFcfPHF+Oqrr/DYY4/hzjvvjKn7z3/+E+3bt8d1112HESNGIDc3F4sWLcKxxx5r1Onfvz++/fZbNGvWDLfeeivOO+883HTTTfjss88swvOJJ56Izz77DE2bNsXw4cPxl7/8BSeddBImTpzo6Tj79OmDDh06YP78+ZZyVVXx/vvvo1u3bhg1ahSuueYaBINBPPXUUzFtlJeXA0DciQkz5513Htq2bYvCwkIMHz4cihIrtZaXl6OgoMBIuEo0XBg3P39BEARBEARBEARBEARBEMQRSYcOHXDiiSfigw8+iFtv8eLF6N+/P/7zn/9gyJAhtdS7xDz66KN44IEHsH37dmRmZia9/Z133ol58+bhl19+SVvi0lmzZuGvf/0rtm3bRhHpDRyKSCcIgiAIgiAIgiAIgiAIosFz8803Izs7G08//XRK2y9atAgTJ05Mm4geDofx0EMPYcKECSSiHwb46roDBEEQBEEQBEEQBEEQBEEQ1SUjIwP//ve/8d1336W0/fLly9Pan23btuGqq67C3/72t7S2S9QNFJFOEARBEIcx1157rZGlXtKhQwdce+21tdqPzZs3gzGG2bNne6q/adMm3HLLLejSpQsyMzPRqFEjnHDCCfj73/+O7du3G/WuvfZaMMaMV+PGjdGhQwcjOVJlZWVM2/369bNsY36tXbvWU//Wr1+PRo0a4YorrohZt3fvXhxzzDE4/fTTEYlEErY1d+5ctGzZEmVlZZ72Xdu4jVWLFi08tzF37lwwxvDcc8/FrPv666+hqipuv/12S3koFEK3bt3w4IMPJt3niRMnomfPntA0zVK+d+9eNGvWDO+++27SbRJ1T0O9n9UXnMbPnkxt3bp1uO+++7B582ZP29clySSC279/Px544AH06tULTZs2RTAYRIcOHTBixAisWrXKqDd79mzLfS4jIwOtW7dG//79MXXqVJSUlMS0fd9997neJ528d+3s27cPeXl5rr8ZS5YsgaqqlqR9bhzuvyfTpk0DYwzvvfee4/oLLrgARx99NHbs2AFAnBv7NTtixAgEg0GsWbMmZvsHH3wQjDG8//77lvKNGzciGAxi6dKlnvppRiYtdPpOJaKgoABNmjSx/LtHcs455+DWW29Nuk2C8MLmzZsT2roA0cSe9cnWRXLWWWdhzJgxdd0NAEDHjh1x7733pi3CnahjOEHUAkuXLuVDhgzhrVu35n6/n+fk5PDLLruMf/3110m1M2nSJJ7qZbto0SIOgC9atCil7b3St29f3rdvX091q6qqeNeuXfnUqVNrtE9e2LNnD8/OzubvvPNOXXeFIIg0Mnz4cN6+fXtL2apVq/iGDRtqtR+//vorB8BfeumlhHXff/993rhxY96+fXs+bdo0/tlnn/GCggI+ffp0ftJJJ/FTTjnFqDt8+HCemZnJly5dypcuXco///xzPmfOHP5///d/XFVVfsIJJ/Bt27ZZ2u/bty/v1KmTsY35dfDgQc/H9Pjjj3MA/M0337SU/9///R/PyMjgP/74Y8I2Dhw4wI855hg+bdo0z/utbQDwIUOGxIzVihUrkmrn4osv5k2aNOG//vqrUVZeXs47d+7Mu3Xrxg8dOmSpP336dN6qVSteXl6edJ/37dvHmzVrxl988cWYdffddx/v3Lkzr6ysTLpdom5piPez+oTT+C1dutRyj/zPf/7j+u/lDRs28FLine truncated
|
||||
"text/plain": [
|
||||
"<Figure size 1500x400 with 4 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"## check that interpolator transforms to uniform distribution \n",
|
||||
"interpolator = Interpolator(H, xedges[:-1], yedges[:-1], ebins[:-1]) #dummy energy bins\n",
|
||||
"CDF_X = interpolator.get_ietax() #lookup table x \n",
|
||||
"CDF_Y = interpolator.get_ietay() #lookup table y \n",
|
||||
"\n",
|
||||
"x_indices = ((x - range[0,0])/bin_width[0]).astype(int)\n",
|
||||
"y_indices = ((y - range[1,0])/bin_width[1]).astype(int)\n",
|
||||
"\n",
|
||||
"u = CDF_X[x_indices, y_indices, 0] #transformed to uniform coordinates\n",
|
||||
"v = CDF_Y[x_indices, y_indices, 0] #transformed to uniform coordinates\n",
|
||||
"\n",
|
||||
"plot(x,y,CDF_X,CDF_Y, u,v)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"id": "85823394",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"shape X_tab: (301, 300, 2)\n",
|
||||
"shape Y_tab: (300, 301, 2)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png":
|
||||
"iVBORw0KGgoAAAANSUhEUgAABdIAAAGWCAYAAAB8cHHOAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzsnXlg1GT+xp83maOFliJXKZZLERDxAlwRVEBcFZFVV5QfqKCoC+KxLh6ILoKyLt6yHuCFAh54rqLihQi6KCgUFRFFAREKLZVCSwu0nZm8vz/evJkkk8xkplNa4PvZHWcmefNeSVP6vN88X8Y55yAIgiAIgiAIgiAIgiAIgiAIwhGlvjtAEARBEARBEARBEARBEARBEA0ZEtIJgiAIgiAIgiAIgiAIgiAIIg4kpBMEQRAEQRAEQRAEQRAEQRBEHEhIJwiCIAiCIAiCIAiCIAiCIIg4kJBOEARBEARBEARBEARBEARBEHEgIZ0gCIIgCIIgCIIgCIIgCIIg4kBCOkEQBEEQBEEQBEEQBEEQBEHEgYR0giAIgiAIgiAIgiAIgiAIgogDCekEQRAEQRAEQRAEQRAEQRAEEQcS0gmCIAiCIAiCIAiCIAiigTN79mwwxsAYw5IlS2L2c87RqVMnMMbQv3///d6/ukKOe9OmTZ7Kjx49Guecc07ddsojv/zyCwKBAFatWlXfXSHSAAnpBEEQBEEQBEEQBEEQBHGAkJ2djVmzZsVs//zzz7FhwwZkZ2fXQ68aBt9++y3mzJmDf/3rX/XdFQBA586dcemll+If//hHfXeFSAMkpBMEQRAEQRAEQRAEQRDEAcKwYcPw1ltvYffu3Zbts2bNwimnnIJ27drVU8/qn/vuuw9/+tOf0KtXr/ruisH111+PL774Al999VV9d4WoJSSkEwRBEARBEARBEARBEMQBwvDhwwEA8+bNM7aVl5fjrbfewujRox2Pufvuu3HyySejWbNmaNKkCXr06IFZs2aBc24p16FDB5x33nl4++23cdxxxyEjIwNHHHEEHnvsMUu5JUuWgDGGl156CePHj0fr1q2RmZmJfv364dtvv41pf+XKlfjLX/6CZs2aISMjAyeeeCJef/31mHLLly9H3759kZGRgTZt2mDixIkIhUKe5mX79u14++23cfnll1u2u1nDyDE42eTEIxQKoVWrVjHtAEBZWRkyMzMxfvx4Y1vPnj1x9NFH46mnnkqqHaLhQUI6QRAEQRAEQRAEQRAEQRwgNGnSBEOHDsXzzz9vbJs3bx4URcGwYcMcj9m0aRPGjBmD119/Hf/973/x17/+FTfccAOmTp0aU/a7777DTTfdhH/84x94++230adPH/z973/HQw89FFP2jjvuwMaNG/Hcc8/hueeew7Zt29C/f39s3LjRKLN48WL07dsXZWVleOqppzB//nyccMIJGDZsGGbPnm2UW7t2LQYOHIiysjLMnj0bTz31FL799lvPNi2ffPIJQqEQBgwY4Kl8qvj9flx22WWOTwXMmzcPVVVVuPLKKy3b+/fvjw8//DBm4YI4sPDVdwcIgiAIgiAIgiAIgiAIgvDO6NGjMWDAAPz444845phj8Pzzz+Piiy929Ud/4YUXjM+apqF///7gnOM///kPJk2aBMaYsX/btm349ttvcfzxxwMABg0ahJKSEkydOhXjxo1Do0aNjLItW7bE22+/bRx/6qmn4qijjsK0adPw7LPPAgDGjRuHY445Bp999hl8PiFFnn322dixYwfuuOMOjBw5Eoqi4J577gHnHJ999hlyc3MBAIMHD0b37t09zcmyZcuQmZmJrl27ep3GlLnyyivx6KOP4rXXXsM111xjbJ89ezZ69uyJY4891lK+R48emDlzJtatW7df+kfUDRSRThAEQRAEQRAEQRAEQRAHEP369cORRx6J559/Hj/88ANWrFjhausCAJ999hnOPPNM5OTkQFVV+P1+3HXXXSgtLUVJSYml7DHHHGOI6JIRI0Zg9+7dWLVqVcx2swjfvn179OnTB4sXLwYArF+/Hj///DMuvfRSAEA4HDZe5557LoqKirBu3ToAInJ94MCBhogOAKqqukbZ29m2bRtatmxp6U9dceyxx6Jnz56WBYqffvoJ33zzjeN5aNWqFQBg69atdd43ou4gIZ0gCIIgCIIgCIIgCIIgDiAYY7jyyivx0ksv4amnnkLnzp1x2mmnOZb95ptvcNZZZwEAnn32WXz55ZdYsWIF7rzzTgDAvn37LOVbt24dU4fcVlpa6qmsLLd9+3YAwC233AK/3295jRs3DgCwY8cOo+54bSdi3759yMjI8FQ2HYwePRrLli3Dzz//DEBE/QeDQcPD3ozsl32uiQMLEtIJgiAIgiAIgiAIgiAI4gDjiiuuwI4dO/DUU0/FeHKbefXVV+H3+/H+++/jkksuQZ8+fdCrVy/X8sXFxa7bmjdv7qmsLNeiRQsAwMSJE7FixQrH1wknnGDUHa/tRLRo0QI7d+6M2S5F7Orqast2KeCnyvDhwxEMBjF79mxEIhG8+OKLuOCCC3DYYYfFlJX9kvNBHJiQkE4QBEEQBEEQBEEQBEEQBxiHH344br31VgwZMgSjRo1yLccYg8/ng6qqxrZ9+/bhxRdfdCz/448/4vvvv7dse+WVV5CdnY0ePXpYts+bN8+SQPP333/HV199hf79+wMAunTpgqOOOgrff/89evXq5fiSvu4DBgzAokWLjCh2AIhEInjttdc8zUfXrl1RWlqK8vJyy/YOHToAAFavXm3Z/u6773qq143DDjsMF1xwAebOnYv3338fxcXFrvY6GzduhKIo6NKlS63aJOoXEtIJgiAIgiAIgiAIgiAI4gDkvvvuwzvvvIO8vDzXMoMHD0ZlZSVGjBiBhQsX4tVXX8Vpp52GYDDoWL5Nmzb4y1/+ghdeeAEfffQRLrvsMixcuBD//Oc/LYlGAaCkpAQXXnghFixYgFdeeQVnnnkmMjIyMHHiRKPM008/jUWLFuHss8/GvHnz8MUXX+Cdd97BtGnTcPHFFxvl/vnPfwIAzjjjDLz22mt47733MHjwYOzZs8fTXMgEql9//bVl+0knnYQuXbrglltuwbx58/DRRx9hzJgxWLp0aUwdS5YsAWMMU6ZM8dTm6NGjUVRUhOuvvx75+fk488wzHcstX74cJ5xwgmO0OnHgQEI6QRAEQRAEQRAEQRAEQRyknHHGGUZS0iFDhuDOO+/E0KFDcfvttzuWP+GEE/DII4/g4Ycfxvnnn48vv/wSjzzyCG677baYsv/+97/Rvn17XHnllRg9ejTy8vKwePFiHHnkkUaZAQMG4JtvvkHTpk1x00034cwzz8S1116LTz/91CI8d+/eHZ9++imaNGmCUaNG4W9/+xuOO+44TJo0ydM4+/btiw4dOmD+/PmW7aqq4r333kPXrl0xduxYjBw5EsFgEE888URMHZWVlQAQd2HCzJlnnom2bduisLAQo0aNgqLESq2VlZVYtGiRkXCVOHBh3Pz8BUEQBEEQBEEQBEEQBEEQhyQdOnRA9+7d8f7778ctt2TJEgwYMABvvPEGhg4dup96l5iHH34Y9957L7Zu3YrMzMykj7/tttswb948/Prrr2lLXDpr1iz8/e9/x5YtWygi/QCHItIJgiAIgiAIgiAIgiAIgjjgue6665CTk4Mnn3wypeMXL16MSZMmpU1ED4fDuP/++zFx4kQS0Q8CfPXdAYIgCIIgCIIgCIIgCIIgiNqSkZGBF198Ed9++21Kx69YsSKt/dmyZQsuu+wy3HzzzWmtl6gfKCKdIAiCIA5irrjiCiNLvaRDhw644oor9ms/Nm3aBMYYZs+e7an8xo0bcf3116Nz587IzMxEo0aNcMwxx+Cf//wntm7dapS74oorwBgzXo0bN0aHDh2M5EjV1dUxdffv399yjPm1Zs0aT/1bt24dGjVqhBEjRsTs27VrFw4//HCcfPLJiEQiCeuaO3cuWrZsiYqKCk9t72/c5qpFixae65g7dy4YY3jmmWdi9n311VdQVRW33HKLZXsoFELXrl1x3333Jd3nSZMmoUePHtA0zbJ9165daNq0Kd55552k6yTqnwP1ftZQcJo/ezK1tWvXYsqUKdi0aZOn4+uTZBLB7d69G/feey969eqFJk2aIBgMokOHDhg9ejRWrVpllJs9e7blPpeRkYHWrVtjwIABmDZtGkpKSmLqnjJliut90sl7105ZWRny8/Ndf2csXboUqqpakva5cbD/PnnwwQfBGMO7777ruP/ss89Gs2bNsG3bNgDi3Niv2dGjRyMYDOKHH36IOf6+++4DYwzvvfeeZfuGDRsQDAaxbNkyT/00I5MWOv1MJWLRokXIysqy/LtHcvrpp+Omm25Kuk6C8MKmTZsS2roA0cSeDcnWRXLqqafihhtuqO9uAAA6duyIu+66K20R7kQ9wwliP7Bs2TI+dOhQ3rp1a+73+3lubi6/6KKL+FdffZVUPZMnT+apXraLFy/mAPjixYtTOt4r/fr14/369fNUtqamhnfp0oVPmzatTvvkhZ07d/KcnBz+9ttv13dXCIJII6NGjeLt27e3bFu1ahVfv379fu3Hb7/9xgHwF154IWHZ9957jzdu3Ji3b9+eP/jgg/zTTz/lixYt4tOnT+fHHXccP+GEE4yyo0aN4pmZmXzZsmV82bJl/LPPPuNz5szh//d//8dVVeXHHHMM37Jli6X+fv368SOOOMI4xvzau3ev5zE9+uijHAB/8803Ldv/7//+j2dkZPCffvopYR179uzhhx9+OH/wwQc9t7u/AcCHDh0aM1crV65Mqp7zzz+fZ2Vl8d9++83YVllZyTt16sS7du3K9+3bZyk/ffp03qpVK15ZWZl0n8vKynjTpk35888/H7NvypQpvFOnTry6ujrpeon65UC8nzUknOZv2bJllnvkG2+84frv5fXr1/NVq1Line truncated
|
||||
"text/plain": [
|
||||
"<Figure size 1500x400 with 4 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"x_indices = ((x - range[0,0])/bin_width[0]).astype(int)\n",
|
||||
"y_indices = ((y - range[1,0])/bin_width[1]).astype(int)\n",
|
||||
"\n",
|
||||
"CDF_X, CDF_Y = calculate_rosenblatt_lookup_table(H, xedges[:-1], yedges[:-1],ebins[:-1])\n",
|
||||
"\n",
|
||||
"u = CDF_X[x_indices, y_indices, 0] #transformed to uniform coordinates\n",
|
||||
"v = CDF_Y[x_indices, y_indices, 0] #transformed to uniform coordinates\n",
|
||||
" \n",
|
||||
"plot(x,y,CDF_X,CDF_Y, u,v)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "fe9e3306",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"worked: \n",
|
||||
"could normalize CDF eta_x\n",
|
||||
"construction worked\n",
|
||||
"calculation of conditional CDF etay worked\n",
|
||||
"assignment m_ietay worked\n",
|
||||
"assignment m_ietax worked\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png":
|
||||
"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aWmGPzM2b94Mu92uEpeMuNB/nsyfPx+SJBk6O4cOHYpmzZohJycHgPzaaN+zkyZNgsPhwC+//BJw/DPPPANJkvDpp5+qth86dAgOhwNbt261NE8RLq7pfU8FY+PGjYiLi9MtyvfnP/8Z9913X8h9Eg2Xa665RinIOWLECDzyyCO4+eab8fDDD+u2v+yyy7Bw4UL897//xciRI/HDDz9g4cKFeOihhwLaPv3002jbti1uv/12TJo0Campqfj2229x0UUXKW0GDRqE7du3o0mTJrjvvvtw7bXX4u6778aGDRtUInLXrl2xYcMGNG7cGBMmTMDf//53dO/eHY8++qil8+zXrx/atWuHtWvXqrbb7XZ8+umn6Ny5M6ZMmYLx48fD4XDoXqdLS0sBwPQmg8i1116L1q1bw+l0YsKECbDZAqXW0tJSbNy4USk2StQTGEEQBEEQFywTJkxgbdu2VW3btWsXy8rKOqfz+OOPPxgAtmLFiqBtP/30UxYbG8vatm3L5s+fzzZs2MA2btzIFi1axLp3784uu+wype2ECRNYTEwM27p1K9u6dSv75ptv2BtvvMH+3//7f8xut7MuXbqw48ePq/ofMGAA69Chg3KM+O/s2bOWz+m5555jANiaNWtU2//f//t/LDo6mv36669B+zhz5gxr1aoVmz9/vuVxzzUA2M033xywVjt37gypn5EjR7K4uDj2xx9/KNtKS0tZeno669y5MysrK1O1X7RoEUtOTmalpaUhz7m4uJg1adKELV++PGDfE088wdLT01l5eXnI/RJ1y/l4PatP6K3f1q1bVdfI999/nwFg3377bcDxWVlZbNeuXbU8S+sAYI8//njQdllZWaxDhw4sLi6OzZgxg3322Wds06ZNbOXKlewvf/kLA8CKi4sZY4ytWLFCeW23bt3Kvv/+e7ZmzRp23333sYSEBNasWTO2fv16Vf+PP/44A8C+/PLLgOtkXl6epXP56quvGAD21FNPqbafOXOGpaens27dugW9ZjWEnycej4ddffXVrEWLFqyoqEi175VXXmEA2OrVq5Vtjz/+eMB73uVysTZt2rDLL7+cVVRUKNv37NnDoqKi2MSJEwPGvfHGG9mwYcNCOFM/3377LQOg+tkXCoMGDWLjx48P2L5p0yYWGRnJDhw4EFa/BGFG27ZtLb3n+fv7/fffPwezss6CBQtY06ZNQ/q9XuTBBx9kaWlpAb+bVofXX3+dxcbGspMnT9ZYn0T1IVGcOCds3bqV3XzzzaxFixYsMjKSpaSksFGjRrEtW7aE1A//pTMc+AVb75f8mmTAgAFswIABltpWVFSwTp06sblz59bqnKxw8uRJlpCQwD766KO6ngpBXNLine truncated
|
||||
"text/plain": [
|
||||
"<Figure size 1500x400 with 4 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"## check that cpp rosenblatt transforms to uniform distribution \n",
|
||||
"interpolator = Interpolator(xedges[:-1], yedges[:-1], ebins[:-1]) #dummy energy bins\n",
|
||||
"interpolator.rosenblatttransform(H)\n",
|
||||
"CDF_X = interpolator.get_ietax() #lookup table x \n",
|
||||
"CDF_Y = interpolator.get_ietay() #lookup table y \n",
|
||||
"\n",
|
||||
"x_indices = ((x - range[0,0])/bin_width[0]).astype(int)\n",
|
||||
"y_indices = ((y - range[1,0])/bin_width[1]).astype(int)\n",
|
||||
"\n",
|
||||
"u = CDF_X[x_indices, y_indices, 0] #transformed to uniform coordinates\n",
|
||||
"v = CDF_Y[x_indices, y_indices, 0] #transformed to uniform coordinates\n",
|
||||
"\n",
|
||||
"plot(x,y,CDF_X,CDF_Y, u,v)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "6df08eb9",
|
||||
"metadata": {},
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a9d088d2",
|
||||
"metadata": {},
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "40a1ffff",
|
||||
"metadata": {},
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "1e0aa9dc",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "base",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.11"
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAbwAAAHFCAYAAACJnUzWAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAA6OdJREFUeJzs/Xl4HNWdLo6/rd60tVuyZK1ty4BsGSxkBzExi4kdSJwhJCgEE25IyALkhvGQDOEmM2HyZU2exzMJYZw7iUmYhBACNyE2mYhfFkDEmInCkiDjRXZsLBvb6la35G5JpW5Jvap+f7RO6dTpc6qqW63Nqvd5eISrq+qcOnXqsy8WWZZlmDBhwoQJE+c4CuZ6AiZMmDBhwsRswGR4JkyYMGFiUcBkeCZMmDBhYlHAZHgmTJgwYWJRwGR4JkyYMGFiUcBkeCZMmDBhYlHAZHgmTJgwYWJRwGR4JkyYMGFiUcBkeCZMmDBhYlHAZHgmcsYbb7yBm266CbW1tXA4HKipqcHWrVvx+uuvZ3WfBx98EBaLJac57N27FxaLBXv37s3peqPYvHkzNm/ebOg8i8UCi8WCgoICuFwuNDY24qabbsLu3bsxMTGRcc3KlSvxuc99Lqv5vPbaa3jwwQcxPDyc1XXsWGT9du/endV9tDA2NoYHH3yQ+06efPJJWCwWnDp1Km/jZYNEIoE1a9bg3/7t3+ZkfBpDQ0MoKyvDb37zm7meyuKBbMJEDvi///f/ygUFBfJll10mP/XUU/Krr74q//znP5cvu+wyuaCgQP7P//xPw/fq7e2VX3/99ZzmIUmS/Prrr8uSJOV0vVFs2rRJ3rRpk6Hzzj//fPn111+XX3/9dfnll1+W/+u//ku+7rrrZADyVVddJQ8PD6uu2bdvn9zT05PVfL7zne/IAOR33303q+vYsV555RUZgLxr166s7qOFs2fPygDkBx54IOO3gYEB+fXXX5ej0WjexssGO3bskKuqquRIJDIn47N48MEH5cbGRjkWi831VBYFTIZnImt0dnbKBQUF8kc+8hE5kUiofkskEvJHPvIRuaCgQO7s7NS8z+jo6ExOM6/IhuGtXbuW+9sTTzwhA5A/8YlPTHs+2TK8sbEx7vHZZnhziUQiIdfX18tf//rX53oqCgKBgGyz2eRnnnlmrqeyKGAyPBNZ47rrrpOtVqvc29vL/f3MmTOy1WqVP/KRjyjHHnjgARmA3NXVJd94441yWVmZXFNTo/qNRjQale+55x65urpaLioqkq+66ir5rbfekhsaGuTPfvazynmEYL/yyivKsc9+9rNySUmJfPz4cfnaa6+VS0pKZI/HI99zzz0ZmsWDDz4ov/e975XLy8tll8slv+c975F//OMfyxMTE6rz8sHwZFmWP/zhD8sWi0U+deqUcox9plQqJX/zm9+UV69eLRcWFsput1u++OKL5R07dqjWi/2PrEFDQ4N83XXXyc8995y8fv162el0yv/yL//CHYus389//nP5K1/5ilxdXS0XFhbK73vf++R9+/YZWoPPfvazckNDgyzLsvzuu+9y50bG/OlPf8pl1D/5yU/klpYW2el0yuXl5fLHPvYx+ciRIxnjGH2vPDz33HMyAPnw4cPKsfHxcXn9+vXyBRdcoNK8/X6/XF1dLW/atElOJpO696Zx9dVXy01NTRl7aGJiQr7gggvkD3/4w6rj1157rXzVVVdlNYaJ3GD68ExkhVQqhVdeeQWXXnopPB4P95zly5ejtbUVe/bsQSqVUv328Y9/HI2Njdi1axd++MMfCsf5/Oc/jx07duDzn/882tvbceONN+KGG24w7LNKJBK4/vrrcc0116C9vR233XYb/uM//gP//u//rjrv1KlT+OIXv4hf/epX+PWvf42Pf/zj+NKXvoRvfvObhsbJFtdffz1kWcaf/vQn4Tnf/va38eCDD+KTn/wkfve73+HZZ5/F7bffrjz7HXfcgS996UsAgF//+td4/fXX8frrr+OSSy5R7rFv3z587Wtfw5e//GW88MILuPHGGzXn9a//+q84efIkfvzjH+PHP/4x+vr6sHnzZpw8eTKr56utrcULL7wAALj99tuVud13333Ca7Zv347bb78da9euxa9//Wt873vfw8GDB3H55Zfj+PHjqnONvlcefve736GqqgoXXXSRcqywsBC/+tWvMDAwgNtuuw0AMDExgU996lOQZRm/+MUvYLVas1qDf/qnf8KxY8fwxz/+UXX8D3/4A06cOIF//Md/VB3fvHkz/vznP2ftjzWRA+aa45pYWAgEAjIA+X/9r/+led7NN98sA5D7+/tlWZ7SSu6///6Mc1kN7/DhwzIARSsh+MUvfqHSFmRZrOEBkH/1q1+prv/whz8sNzU1CeecSqXkRCIhP/zww3JFRYVKQs+XhveHP/xBBiD/+7//u3KM1bo+8pGPyOvXr9ccR8uk2dDQIFutVvnYsWPc33jrd8kll6ie99SpU7LdbpfvuOMO1bPpaXiyrG3SZDW8oaEhuaioKEPrOXPmjOx0OuVbbrlFNU4u75XgwgsvlP/+7/+e+9uzzz4rA5B37Ngh33///XJBQYH80ksv6d6Th1QqJZ9//vlyW1ub6vi1114rX3DBBRmaX0dHhwxA/sMf/pDTeCaMw9TwTMwI5Mk2i2z0pZ6mAQCvvvoqAOATn/iE6vjWrVths9kMjW+xWPDRj35UdaylpQWnT59WHduzZw8+8IEPwO12w2q1wm634/7770coFMLAwIChsbKBbKD95Hvf+14cOHAA27Ztw4svvoiRkZGsx2lpacHq1asNn3/LLbeo3lVDQwOuuOIKvPLKK1mPnQ1ef/11jI+PZ0SpLl++HFdffXWGlmT0vfLQ19eHqqoq7m+f+MQn8A//8A/42te+hm9961v413/9V3zwgx/M7mEmUVBQgLvuugu//e1vcebMGQDAiRMn8MILL2Dbtm0Z3wSZk8/ny2k8E8ZhMjwTWaGyshLFxcV49913Nc87deoUiouLsXTpUtXx2tpa3TFCoRAAoLq6WnXcZrOhoqLC0DyLi4tRWFioOuZ0OhGNRpV//+Uvf8GWLVsAAP/1X/+FP//5z/jrX/+Kb3zjGwCA8fFxQ2NlA0KY6+rqhOfce++9eOSRR/DGG2/g2muvRUVFBa655hq89dZbhscxss40ampquMfIu5gpkPvz5ltXV5cxvpH3KsL4+HjGtTRuu+02JBIJ2Gw2fPnLXzYyfc17FRUVKWb7H/zgBygqKlLMpjTInGZiv5lQw2R4JrKC1WrF+9//frz11lvwer3cc7xeL7q6unD11Vdn+D+M5NsRptbf3686nkwm80qAf/nLX8Jut+O3v/0tPvGJT+CKK67ApZdemrf78/D888/DYrHgfe97n/Acm82Ge+65B/v27cPg4CB+8YtfoLe3Fx/60IcwNjZmaJxs8xoDgQD3GC1gFBYWIhaLZZwXDAazGosGub/f78/4ra+vD5WVlTnfm0VlZSUGBwe5v42OjuLWW2/F6tWrUVRUhDvuuGNaY7ndbnz2s5/Fj3/8YwwODuKnP/0pbrnlFpSVlWWcS+aUz2c1wYfJ8ExkjXvvvReyLGPbtm0ZQSmpVAr/8A//AFmWce+99+Z0f8IMnn32WdXx3bt3I5lM5jZpDiwWC2w2m4opj4+P4+c//3nexqDx05/+FH/4wx/wyU9+EitWrDB0TVlZGbZu3Yp//Md/xODgoJKw7XQ6lfnmA7/4xS9U5tbTp0/jtddeUyXbr1y5Eu+8846K6YVCIbz22muqe2Uzt8svvxxFRUV4+umnVce9Xi/27NmDa665JpfH4WLNmjU4ceIE97c777wTZ86cwa9//Wv85Cc/wfPPP4//+I//mNZ4X/7ylxEMBrF161YMDw/jrrvu4p5HAoPoYBoTMwNjDhETJihceeWV2LFjB+6++25s3LgRd911F1asWIEzZ87gBz/4Ad58803s2LEDV1xxRU73X7t2LT75yU/iu9/9LqxWK66++mocPnwY3/3ud+F2u1FQkB857brrrsOjjz6KW265Bf/7f/9vhEIhPPLIIwrBzhXj4+N44403lP8/efIkfvOb3+C3v/0tNm3apBmdCgAf/ehH0dzcjEsvvRTLli3D6dOnsWPHDjQ0NGDVqlUAgIsvvhgA8L3vfQ+f/exnYbfb0dTUBJfLldOcBwYGcMMNN+ALX/gCJEnCAw88gMLCQpXQcuutt+JHP/oRPv3pT+MLX/gCQqEQvv3tb2PJkiWqe7lcLjQ0NKC9vR3XXHMNli5disrKSqxcuTJj3LKyMtx3333413/9V3zmM5/BJz/5SYRCITz00EMoLCzEAw88kNPz8LB582Y8/PDDGBsbQ3FxsXL8xz/+MZ5++mn89Kc/xdq1a7F27Vrcdddd+Jd/+RdceeWVeO973wsgbaY/77zz8NnPfhZPPvmk7nirV6/G3//93+MPf/gDNm7ciHXr1nHPe+ONN1BRUaG8UxMziDkNmTGxoPH666/LW7dulaurq2WbzSZXVVXJH//4x+XXXnst41wSiXn27FnhbzRIHl5VVZVcWFgoX3bZZfLrr78uu91u+Stf+YpynlYenpFxnnjiCbmpqUl2Op3y+eefL2/fvl3+yU9+khEBmU2UJqj8s5KSEvn888+Xt27dKu/atUtOpVIZ17CRk9/97nflK664Qq6srJQdDoe8YsUK+fbbb1fl7smyLN97771yXV2dXFBQwM3D40ErD+/LX/6yvGzZMtnpdCp5jyx+9rOfyRdeeKFcWFgoX3TRRfKzzz6bEaUpy7L88ssvy+95z3tkp9NpKA/vxz/+sdzS0iI7HA7Z7XbLbW1tqnw5Wc7uvfLQ09MjWywWVZTnwYMH5aKiItWayHJ6/7W2tsorV66Uh4aGZFmW5UOHDskAskpcf/LJJ2UA8i9/+Uvu7xMTE3JDQ4P8pS99yfA9TeQOiywbCBszYWIe4LXXXsOLine truncated
|
||||
"text/plain": [
|
||||
"<Figure size 640x480 with 1 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"## joint conditional distribution \n",
|
||||
"rng = np.random.default_rng(42)\n",
|
||||
"n = 10_000_000 \n",
|
||||
" \n",
|
||||
"## circular distribution x,y dependant \n",
|
||||
"theta = rng.uniform(0, 4*np.pi, size=n)\n",
|
||||
"r = rng.uniform(0.3, 0.4) \n",
|
||||
"#r = 0.3 + 0.4 * (theta / (4*np.pi)) # 螺旋半径从 0.3 到 0.7\n",
|
||||
"x_raw = r * np.cos(theta) + 0.1 * rng.normal(size=n)\n",
|
||||
"y_raw = r * np.sin(theta) + 0.1 * rng.normal(size=n)\n",
|
||||
" \n",
|
||||
"# scale to [0, 1]\n",
|
||||
"x = (x_raw - x_raw.min()) / (x_raw.max() - x_raw.min())\n",
|
||||
"y = (y_raw - y_raw.min()) / (y_raw.max() - y_raw.min())\n",
|
||||
" \n",
|
||||
"plt.scatter(x[:5000], y[:5000], s=1, alpha=0.5)\n",
|
||||
"plt.title(\"Original Distribution (x, y)\")\n",
|
||||
"plt.gca().set_aspect('equal')\n",
|
||||
"plt.xlabel(\"x\")\n",
|
||||
"plt.ylabel(\"y\")\n",
|
||||
" "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "a713be97",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def plot(x, y, CDF_X, CDF_Y, u, v): \n",
|
||||
" #plot\n",
|
||||
" fig, axs = plt.subplots(1, 4, figsize=(15, 4))\n",
|
||||
" \n",
|
||||
" axs[0].scatter(x[:5000], y[:5000], s=1, alpha=0.5)\n",
|
||||
" axs[0].set_title(\"Original (x, y)\")\n",
|
||||
" axs[0].set_aspect('equal')\n",
|
||||
" axs[0].set_xlabel(\"x\")\n",
|
||||
" axs[0].set_ylabel(\"y\")\n",
|
||||
" \n",
|
||||
" axs[1].imshow(CDF_X[:,:,0], origin='lower', extent=[0,1,0,1], cmap='viridis')\n",
|
||||
" axs[1].set_title(\"normalized CDF_X (u = F_X(x))\")\n",
|
||||
" axs[1].set_xlabel(\"y\")\n",
|
||||
" axs[1].set_ylabel(\"P_X(x < x')\")\n",
|
||||
"\n",
|
||||
" axs[2].imshow(CDF_Y[:,:,0], origin='lower', extent=[0,1,0,1], cmap='viridis')\n",
|
||||
" axs[2].set_title(\"normalized conditional CDF_Y (u = F_Y|X(y|x))\")\n",
|
||||
" axs[2].set_xlabel(\"P_Y|X(y < y'|x)\")\n",
|
||||
" axs[2].set_ylabel(\"x\")\n",
|
||||
"\n",
|
||||
" axs[3].scatter(u[:5000], v[:5000], s=1, alpha=0.5, color='blue')\n",
|
||||
" axs[3].set_title(\"Mapped (u, v)\")\n",
|
||||
" axs[3].set_aspect('equal')\n",
|
||||
" axs[3].set_xlim(0,1); axs[2].set_ylim(0,1)\n",
|
||||
" axs[3].set_xlabel(\"u\")\n",
|
||||
" axs[3].set_ylabel(\"v\")\n",
|
||||
" \n",
|
||||
" plt.tight_layout()\n",
|
||||
" plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "0e87346a",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"(300, 300, 2)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"#calculate joint probability density function\n",
|
||||
"nBins = 300\n",
|
||||
"range = np.array([[x.min(),x.max()], [y.min(),y.max()]])\n",
|
||||
"bin_width = (range[:,0] - range[:,1])/nBins\n",
|
||||
"H, xedges, yedges = np.histogram2d(x, y, bins=nBins, range=range)\n",
|
||||
"H = H.astype(int) \n",
|
||||
"H = np.repeat(H[:,:,None], 2, axis=2) #add energy axis\n",
|
||||
"\n",
|
||||
"print(H.shape)\n",
|
||||
"ebins = [0,1,2] #dummy energy bins"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "d63e9295",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAABdIAAAGWCAYAAAB8cHHOAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzsnXl8FEX6xp/qniMBQlCOEAynCIjiQXBVUAFxdRFZdWXlhxeKuiAKq6yK6CIi66LiwXqAFwqsirpeqHhhBF0UlEMFFkUBOQIJkSskQJKZ6fr9UV093T3dMz2TyQXv188409XV1dXVPT3kqbefl3HOOQiCIAiCIAiCIAiCIAiCIAiCcESp6w4QBEEQBEEQBEEQBEEQBEEQRH2GhHSCIAiCIAiCIAiCIAiCIAiCiAMJ6QRBEARBEARBEARBEARBEAQRBxLSCYIgCIIgCIIgCIIgCIIgCCIOJKQTBEEQBEEQBEEQBEEQBEEQRBxISCcIgiAIgiAIgiAIgiAIgiCIOJCQThAEQRAEQRAEQRAEQRAEQRBxICGdIAiCIAiCIAiCIAiCIAiCIOJAQjpBEARBEARBEARBEARBEARBxIGEdIIgCIIgCIIgCIIgCIKo58yePRuMMTDGsHjx4pj1nHN07twZjDH069ev1vtXU8jj3rx5s6f6I0aMwB/+8Iea7ZRHfv75ZwQCAaxataquu0KkARLSCYIgCIIgCIIgCIIgCKKBkJWVhVmzZsWUf/HFF9i4cSOysrLqoFf1g++++w5z5szBP/7xj7ruCgCgS5cuuPLKK3HbbbfVdVeINEBCOkEQBEEQBEEQBEEQBEE0EIYOHYq33noL+/fvt5TPmjULZ555Jtq1a1dHPat7HnzwQfzud79Dr1696rorBrfccgu+/PJLfP3113XdFaKakJBOEARBEARBEARBEARBEA2EYcOGAQDmzZtnlJWWluKtt97CiBEjHLeZPHkyTj/9dBx99NFo2rQpevbsiVmzZoFzbqnXoUMHXHTRRXjnnXdw0kknISMjA506dcITTzxhqbd48WIwxvDyyy9j3LhxaN26NTIzM9G3b1989913MftfsWIF/vjHP+Loo49GRkYGTj31VLzxxhsx9ZYtW4Y+ffogIyMDbdq0wYQJExAKhTyNy86dO/HOO+/g6quvtpS7WcPIY3CyyYlHKBRCq1atYvYDAPv27UNmZibGjRtnlOXn5+P444/HM888k9R+iPoHCekEQRAEQRAEQRAEQRAE0UBo2rQphgwZghdffNEomzdvHhRFwdChQx232bx5M0aOHIk33ngDb7/9Nv70pz9hzJgxmDJlSkzd77//Hrfeeituu+02vPPOO+jduzf++te/4pFHHompe/fdd2PTpk144YUX8MILL2DHjh3o168fNm3aZNRZtGgR+vTpg3379uGZZ57B/Pnzccopp2Do0KGYPXu2UW/dunUYMGAA9u3bh9mzZ+OZZ57Bd99959mm5dNPP0UoFEL//v091U8Vv9+Pq666yvGpgHnz5qGiogLXXXedpbxfv3746KOPYiYuiIaFr647QBAEQRAEQRAEQRAEQRCEd0aMGIH+/fvjf//7H0444QS8+OKL+POf/+zqj/7SSy8ZnzVNQ79+/cA5x7/+9S9MnDgRjDFj/Y4dO/Ddd9/h5JNPBgAMHDgQJSUlmDJlCkaPHo1GjRoZdVu2bIl33nnH2P6ss87Ccccdh6lTp+L5558HAIwePRonnHACPv/8c/h8Qoq84IILsGvXLtx999245pproCgK7r//fnDO8fnnnyMnJwcAMGjQIJx44omexmTp0qXIzMxEt27dvA5jylx33XV4/PHH8frrr+PGG280ymfPno38/Hz06NHDUr9nz56YOXMm1q9fXyv9I2oGikgnCIIgCIIgCIIgCIIgiAZE3759ceyxx+LFF1/EmjVrsHz5cldbFwD4/PPPcd555yE7OxuqqsLv9+Pee+/F7t27UVJSYql7wgknGCK65IorrsD+/fuxatWqmHKzCN++fXv07t0bixYtAgBs2LABP/30E6688koAQDgcNl4XXnghioqKsH79egAicn3AgAGGiA4Aqqq6Rtnb2bFjB1q2bGnpT03Ro0cP5OfnWyYofvzxR3z77beO56FVq1YAgO3bt9d434iag4R0giAIgiAIgiAIgiAIgmhAMMZw3XXX4eWXX8YzzzyDLl264Oyzz3as++233+L8888HADz//PP46quvsHz5ctxzzz0AgEOHDlnqt27dOqYNWbZ7925PdWW9nTt3AgBuv/12+P1+y2v06NEAgF27dhltx9t3Ig4dOoSMjAxPddPBiBEjsHTpUvz0008ARNR/MBg0POzNyH7Zx5poWJCQThAEQRAEQRAEQRAEQRANjGuvvRa7du3CM888E+PJbea1116D3+/HBx98gMsvvxy9e/dGr169XOsXFxe7ljVv3txTXVmvRYsWAIAJEyZg+fLljq9TTjnFaDvevhPRokUL7NmzJ6ZcitiVlZWWcingp8qwYcMQDAYxe/ZsRCIR/Pvf/8Yll1yCo446Kqau7JccD6JhQkI6QRAEQRAEQRAEQRAEQTQwjjnmGNxxxx0YPHgwhg8f7lqPMQafzwdVVY2yQ4cO4d///rdj/f/973/44YcfLGWvvvoqsrKy0LNnT0v5vHnzLAk0t2zZgq+//hr9+vUDAHTt2hXHHXccfvjhB/Tq1cvxJX3d+/fvj4KCAiOKHQAikQhef/11T+PRrVs37N69G6WlpZbyDh06AABWr15tKX/vvfc8tevGUUcdhUsuuQRz587FBx98gOLiYld7nU2bNkFRFHTt2rVa+yTqFhLSCYIgCIIgCIIgCIIgCKIB8uCDD+Ldd99Fbm6ua51BgwahvLwcV1xxBRYuXIjXXnsNZ599NoLBoGP9Nm3a4I9//CNeeuklfPzxx7jqqquwcOFC/P3vf7ckGgWAkpISXHrppViwYAFeffVVnHfeecjIyMCECROMOs8++ywKCgpwwQUXYN68efjyyy/x7rvvYurUqfjzn/9s1Pv73/8OADj33HPx+uuv4/3338egQYNw4MABT2MhE6h+8803lvLTTjsNXbt2xe2334558+bh448/xsiRI7FkyZKYNhYvXgzGGO677z5P+xwxYgSKiopwyy23IC8vD+edd55jvWXLluGUU05xjFYnGg4kpBMEQRAEQRAEQRAEQRDEYcq5555rJCUdPHgw7rnnHgwZMgR33XWXY/1TTjkFjz32GB599FFcfPHF+Oqrr/DYY4/hzjvvjKn7z3/+E+3bt8d1112HESNGIDc3F4sWLcKxxx5r1Onfvz++/fZbNGvWDLfeeivOO+883HTTTfjss88swvOJJ56Izz77DE2bNsXw4cPxl7/8BSeddBImTpzo6Tj79OmDDh06YP78+ZZyVVXx/vvvo1u3bhg1ahSuueYaBINBPPXUUzFtlJeXA0DciQkz5513Htq2bYvCwkIMHz4cihIrtZaXl6OgoMBIuEo0XBg3P39BEARBEARBEARBEARBEMQRSYcOHXDiiSfigw8+iFtv8eLF6N+/P/7zn/9gyJAhtdS7xDz66KN44IEHsH37dmRmZia9/Z133ol58+bhl19+SVvi0lmzZuGvf/0rtm3bRhHpDRyKSCcIgiAIgiAIgiAIgiAIosFz8803Izs7G08//XRK2y9atAgTJ05Mm4geDofx0EMPYcKECSSiHwb46roDBEEQBEEQBEEQBEEQBEEQ1SUjIwP//ve/8d1336W0/fLly9Pan23btuGqq67C3/72t7S2S9QNFJFOEARBEIcx1157rZGlXtKhQwdce+21tdqPzZs3gzGG2bNne6q/adMm3HLLLejSpQsyMzPRqFEjnHDCCfj73/+O7du3G/WuvfZaMMaMV+PGjdGhQwcjOVJlZWVM2/369bNsY36tXbvWU//Wr1+PRo0a4YorrohZt3fvXhxzzDE4/fTTEYlEErY1d+5ctGzZEmVlZZ72Xdu4jVWLFi08tzF37lwwxvDcc8/FrPv666+hqipuv/12S3koFEK3bt3w4IMPJt3niRMnomfPntA0zVK+d+9eNGvWDO+++27SbRJ1T0O9n9UXnMbPnkxt3bp1uO+++7B582ZP29clySSC279/Px544AH06tULTZs2RTAYRIcOHTBixAisWrXKqDd79mzLfS4jIwOtW7dG//79MXXqVJSUlMS0fd9997neJ528d+3s27cPeXl5rr8ZS5YsgaqqlqR9bhzuvyfTpk0DYwzvvfee4/oLLrgARx99NHbs2AFAnBv7NTtixAgEg0GsWbMmZvsHH3wQjDG8//77lvKNGzciGAxi6dKlnvppRiYtdPpOJaKgoABNmjSx/LtHcs455+DWW29Nuk2C8MLmzZsT2roA0cSe9cnWRXLWWWdhzJgxdd0NAEDHjh1x7733pi3CnahjOEHUAkuXLuVDhgzhrVu35n6/n+fk5PDLLruMf/3110m1M2nSJJ7qZbto0SIOgC9atCil7b3St29f3rdvX091q6qqeNeuXfnUqVNrtE9e2LNnD8/OzubvvPNOXXeFIIg0Mnz4cN6+fXtL2apVq/iGDRtqtR+//vorB8BfeumlhHXff/993rhxY96+fXs+bdo0/tlnn/GCggI+ffp0ftJJJ/FTTjnFqDt8+HCemZnJly5dypcuXco///xzPmfOHP5///d/XFVVfsIJJ/Bt27ZZ2u/bty/v1KmTsY35dfDgQc/H9Pjjj3MA/M0337SU/9///R/PyMjgP/74Y8I2Dhw4wI855hg+bdo0z/utbQDwIUOGxIzVihUrkmrn4osv5k2aNOG//vqrUVZeXs47d+7Mu3Xrxg8dOmSpP336dN6qVSteXl6edJ/37dvHmzVrxl988cWYdffddx/v3Lkzr6ysTLpdom5piPez+oTT+C1dutRyj/zPf/7j+u/lDRs28FWrVtVwL70DgE+Line truncated
|
||||
"text/plain": [
|
||||
"<Figure size 1500x400 with 4 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"## check that interpolator transforms to uniform distribution \n",
|
||||
"interpolator = Interpolator(H, xedges[:-1], yedges[:-1], ebins[:-1]) #dummy energy bins\n",
|
||||
"CDF_X = interpolator.get_ietax() #lookup table x \n",
|
||||
"CDF_Y = interpolator.get_ietay() #lookup table y \n",
|
||||
"\n",
|
||||
"x_indices = ((x - range[0,0])/bin_width[0]).astype(int)\n",
|
||||
"y_indices = ((y - range[1,0])/bin_width[1]).astype(int)\n",
|
||||
"\n",
|
||||
"u = CDF_X[x_indices, y_indices, 0] #transformed to uniform coordinates\n",
|
||||
"v = CDF_Y[x_indices, y_indices, 0] #transformed to uniform coordinates\n",
|
||||
"\n",
|
||||
"plot(x,y,CDF_X,CDF_Y, u,v)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"id": "85823394",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"shape X_tab: (301, 300, 2)\n",
|
||||
"shape Y_tab: (300, 301, 2)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAABdIAAAGWCAYAAAB8cHHOAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzsnXlg1GT+xp83maOFliJXKZZLERDxAlwRVEBcFZFVV5QfqKCoC+KxLh6ILoKyLt6yHuCFAh54rqLihQi6KCgUFRFFAREKLZVCSwu0nZm8vz/evJkkk8xkplNa4PvZHWcmefNeSVP6vN88X8Y55yAIgiAIgiAIgiAIgiAIgiAIwhGlvjtAEARBEARBEARBEARBEARBEA0ZEtIJgiAIgiAIgiAIgiAIgiAIIg4kpBMEQRAEQRAEQRAEQRAEQRBEHEhIJwiCIAiCIAiCIAiCIAiCIIg4kJBOEARBEARBEARBEARBEARBEHEgIZ0gCIIgCIIgCIIgCIIgCIIg4kBCOkEQBEEQBEEQBEEQBEEQBEHEgYR0giAIgiAIgiAIgiAIgiAIgogDCekEQRAEQRAEQRAEQRAEQRAEEQcS0gmCIAiCIAiCIAiCIAiigTN79mwwxsAYw5IlS2L2c87RqVMnMMbQv3///d6/ukKOe9OmTZ7Kjx49Guecc07ddsojv/zyCwKBAFatWlXfXSHSAAnpBEEQBEEQBEEQBEEQBHGAkJ2djVmzZsVs//zzz7FhwwZkZ2fXQ68aBt9++y3mzJmDf/3rX/XdFQBA586dcemll+If//hHfXeFSAMkpBMEQRAEQRAEQRAEQRDEAcKwYcPw1ltvYffu3Zbts2bNwimnnIJ27drVU8/qn/vuuw9/+tOf0KtXr/ruisH111+PL774Al999VV9d4WoJSSkEwRBEARBEARBEARBEMQBwvDhwwEA8+bNM7aVl5fjrbfewujRox2Pufvuu3HyySejWbNmaNKkCXr06IFZs2aBc24p16FDB5x33nl4++23cdxxxyEjIwNHHHEEHnvsMUu5JUuWgDGGl156CePHj0fr1q2RmZmJfv364dtvv41pf+XKlfjLX/6CZs2aISMjAyeeeCJef/31mHLLly9H3759kZGRgTZt2mDixIkIhUKe5mX79u14++23cfnll1u2u1nDyDE42eTEIxQKoVWrVjHtAEBZWRkyMzMxfvx4Y1vPnj1x9NFH46mnnkqqHaLhQUI6QRAEQRAEQRAEQRAEQRwgNGnSBEOHDsXzzz9vbJs3bx4URcGwYcMcj9m0aRPGjBmD119/Hf/973/x17/+FTfccAOmTp0aU/a7777DTTfdhH/84x94++230adPH/z973/HQw89FFP2jjvuwMaNG/Hcc8/hueeew7Zt29C/f39s3LjRKLN48WL07dsXZWVleOqppzB//nyccMIJGDZsGGbPnm2UW7t2LQYOHIiysjLMnj0bTz31FL799lvPNi2ffPIJQqEQBgwY4Kl8qvj9flx22WWOTwXMmzcPVVVVuPLKKy3b+/fvjw8//DBm4YI4sPDVdwcIgiAIgiAIgiAIgiAIgvDO6NGjMWDAAPz444845phj8Pzzz+Piiy929Ud/4YUXjM+apqF///7gnOM///kPJk2aBMaYsX/btm349ttvcfzxxwMABg0ahJKSEkydOhXjxo1Do0aNjLItW7bE22+/bRx/6qmn4qijjsK0adPw7LPPAgDGjRuHY445Bp999hl8PiFFnn322dixYwfuuOMOjBw5Eoqi4J577gHnHJ999hlyc3MBAIMHD0b37t09zcmyZcuQmZmJrl27ep3GlLnyyivx6KOP4rXXXsM111xjbJ89ezZ69uyJY4891lK+R48emDlzJtatW7df+kfUDRSRThAEQRAEQRAEQRAEQRAHEP369cORRx6J559/Hj/88ANWrFjhausCAJ999hnOPPNM5OTkQFVV+P1+3HXXXSgtLUVJSYml7DHHHGOI6JIRI0Zg9+7dWLVqVcx2swjfvn179OnTB4sXLwYArF+/Hj///DMuvfRSAEA4HDZe5557LoqKirBu3ToAInJ94MCBhogOAKqqukbZ29m2bRtatmxp6U9dceyxx6Jnz56WBYqffvoJ33zzjeN5aNWqFQBg69atdd43ou4gIZ0gCIIgCIIgCIIgCIIgDiAYY7jyyivx0ksv4amnnkLnzp1x2mmnOZb95ptvcNZZZwEAnn32WXz55ZdYsWIF7rzzTgDAvn37LOVbt24dU4fcVlpa6qmsLLd9+3YAwC233AK/3295jRs3DgCwY8cOo+54bSdi3759yMjI8FQ2HYwePRrLli3Dzz//DEBE/QeDQcPD3ozsl32uiQMLEtIJgiAIgiAIgiAIgiAI4gDjiiuuwI4d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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 1500x400 with 4 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"x_indices = ((x - range[0,0])/bin_width[0]).astype(int)\n",
|
||||
"y_indices = ((y - range[1,0])/bin_width[1]).astype(int)\n",
|
||||
"\n",
|
||||
"CDF_X, CDF_Y = calculate_rosenblatt_lookup_table(H, xedges[:-1], yedges[:-1],ebins[:-1])\n",
|
||||
"\n",
|
||||
"u = CDF_X[x_indices, y_indices, 0] #transformed to uniform coordinates\n",
|
||||
"v = CDF_Y[x_indices, y_indices, 0] #transformed to uniform coordinates\n",
|
||||
" \n",
|
||||
"plot(x,y,CDF_X,CDF_Y, u,v)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "fe9e3306",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"worked: \n",
|
||||
"could normalize CDF eta_x\n",
|
||||
"construction worked\n",
|
||||
"calculation of conditional CDF etay worked\n",
|
||||
"assignment m_ietay worked\n",
|
||||
"assignment m_ietax worked\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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aWmGPzM2b94Mu92uEpeMuNB/nsyfPx+SJBk6O4cOHYpmzZohJycHgPzaaN+zkyZNgsPhwC+//BJw/DPPPANJkvDpp5+qth86dAgOhwNbt261NE8RLq7pfU8FY+PGjYiLi9MtyvfnP/8Z9913X8h9Eg2Xa665RinIOWLECDzyyCO4+eab8fDDD+u2v+yyy7Bw4UL897//xciRI/HDDz9g4cKFeOihhwLaPv3002jbti1uv/12TJo0Campqfj2229x0UUXKW0GDRqE7du3o0mTJrjvvvtw7bXX4u6778aGDRtUInLXrl2xYcMGNG7cGBMmTMDf//53dO/eHY8++qil8+zXrx/atWuHtWvXqrbb7XZ8+umn6Ny5M6ZMmYLx48fD4XDoXqdLS0sBwPQmg8i1116L1q1bw+l0YsKECbDZAqXW0tJSbNy4USk2StQTGEEQBEEQFywTJkxgbdu2VW3btWsXy8rKOqfz+OOPPxgAtmLFiqBtP/30UxYbG8vatm3L5s+fzzZs2MA2btzIFi1axLp3784uu+wype2ECRNYTEwM27p1K9u6dSv75ptv2BtvvMH+3//7f8xut7MuXbqw48ePq/ofMGAA69Chg3KM+O/s2bOWz+m5555jANiaNWtU2//f//t/LDo6mv36669B+zhz5gxr1aoVmz9/vuVxzzUA2M033xywVjt37gypn5EjR7K4uDj2xx9/KNtKS0tZeno669y5MysrK1O1X7RoEUtOTmalpaUhz7m4uJg1adKELV++PGDfE088wdLT01l5eXnI/RJ1y/l4PatP6K3f1q1bVdfI999/nwFg3377bcDxWVlZbNeuXbU8S+sAYI8//njQdllZWaxDhw4sLi6OzZgxg3322Wds06ZNbOXKlewvf/kLA8CKi4sZY4ytWLFCeW23bt3Kvv/+e7ZmzRp23333sYSEBNasWTO2fv16Vf+PP/44A8C+/PLLgOtkXl6epXP56quvGAD21FNPqbafOXOGpaens27dugW9ZjWEnycej4ddffXVrEWLFqyoqEi175VXXmEA2OrVq5Vtjz/+eMB73uVysTZt2rDLL7+cVVRUKNv37NnDoqKi2MSJEwPGvfHGG9mwYcNCOFM/3377LQOg+tkXCoMGDWLjx48P2L5p0yYWGRnJDhw4EFa/BGFG27ZtLb3n+fv7/fffPwezss6CBQtY06ZNQ/q9XuTBBx9kaWlpAb+bVofXX3+dxcbGspMnT9ZYn0T1IVGcOCds3bqV3XzzzaxFixYsMjKSpaSksFGjRrEtW7aE1A//pTMc+AVb75f8mmTAgAFswIABltpWVFSwTp06sblz59bqnKxw8uRJlpCQwD766KO6ngpBXNCE+8tZuOiJIHWLine truncated
|
||||
"text/plain": [
|
||||
"<Figure size 1500x400 with 4 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"## check that cpp rosenblatt transforms to uniform distribution \n",
|
||||
"interpolator = Interpolator(xedges[:-1], yedges[:-1], ebins[:-1]) #dummy energy bins\n",
|
||||
"interpolator.rosenblatttransform(H)\n",
|
||||
"CDF_X = interpolator.get_ietax() #lookup table x \n",
|
||||
"CDF_Y = interpolator.get_ietay() #lookup table y \n",
|
||||
"\n",
|
||||
"x_indices = ((x - range[0,0])/bin_width[0]).astype(int)\n",
|
||||
"y_indices = ((y - range[1,0])/bin_width[1]).astype(int)\n",
|
||||
"\n",
|
||||
"u = CDF_X[x_indices, y_indices, 0] #transformed to uniform coordinates\n",
|
||||
"v = CDF_Y[x_indices, y_indices, 0] #transformed to uniform coordinates\n",
|
||||
"\n",
|
||||
"plot(x,y,CDF_X,CDF_Y, u,v)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "6df08eb9",
|
||||
"metadata": {},
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a9d088d2",
|
||||
"metadata": {},
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "40a1ffff",
|
||||
"metadata": {},
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "1e0aa9dc",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "base",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.11"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -109,4 +109,22 @@ def test_3x3_reduction():
|
||||
assert reduced_cv.size == 2
|
||||
assert reduced_cv[0]["x"] == 5
|
||||
assert reduced_cv[0]["y"] == 5
|
||||
assert (reduced_cv[0]["data"] == np.array([[2.0, 1.0, 1.0], [2.0, 3.0, 1.0], [2.0, 1.0, 1.0]], dtype=np.double)).all()
|
||||
assert (reduced_cv[0]["data"] == np.array([[2.0, 1.0, 1.0], [2.0, 3.0, 1.0], [2.0, 1.0, 1.0]], dtype=np.double)).all()
|
||||
|
||||
|
||||
def test_masking():
|
||||
|
||||
cv = _aare.ClusterVector_Cluster3x3i()
|
||||
cv.push_back(_aare.Cluster3x3i(19, 22, np.array([0,1,0,2,3,0,2,1,0], dtype=np.int32)))
|
||||
cv.push_back(_aare.Cluster3x3i(1, 2, np.ones(9, dtype=np.int32)))
|
||||
assert cv.size == 2
|
||||
|
||||
mask = np.array([False, True], dtype=bool)
|
||||
cv_masked = cv(mask)
|
||||
assert cv_masked.size == 1
|
||||
|
||||
cv_masked_array = np.array(cv_masked, copy=False)
|
||||
|
||||
assert cv_masked_array[0]["x"] == 1
|
||||
assert cv_masked_array[0]["y"] == 2
|
||||
assert (cv_masked_array[0]["data"] == np.ones((3,3),dtype=np.int32)).all()
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,174 +1,175 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "efef8e20-6571-4561-8f0b-6048b57907de",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"import sys\n",
|
||||
"sys.path.insert(0, '/home/ferjao_k/sw/aare/build')\n",
|
||||
"from aare import Pol1, Pol2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8449f9e9-59ee-4194-b477-d014b8efc93b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Ground truth\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "35772e2c-37c6-4986-a9c0-7dca4a034827",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"x = np.linspace(0, 10, 50)\n",
|
||||
" \n",
|
||||
"# Pol1: y = 3.0 + 1.5*x\n",
|
||||
"true_pol1 = [3.0, 1.5]\n",
|
||||
"y_pol1 = true_pol1[0] + true_pol1[1] * x\n",
|
||||
"y_pol1_noisy = y_pol1 + np.random.default_rng(42).normal(0, 0.5, x.size)\n",
|
||||
" \n",
|
||||
"# Pol2: y = 2.0 - 0.5*x + 0.3*x^2\n",
|
||||
"true_pol2 = [2.0, -0.5, 0.3]\n",
|
||||
"y_pol2 = true_pol2[0] + true_pol2[1] * x + true_pol2[2] * x**2\n",
|
||||
"y_pol2_noisy = y_pol2 + np.random.default_rng(7).normal(0, 1.0, x.size)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a318ab93-fe18-4798-9ddb-6ffc2c2e3875",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Fit with error estimation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"id": "06c8fddb-56d9-4f84-8b21-4ffd8b7bd26f",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"=== Pol1 ===\n",
|
||||
" True: p0=3.0000 p1=1.5000\n",
|
||||
" Fitted: p0=2.9325 p1=1.5226\n",
|
||||
" Chi2: [7.00870822]\n",
|
||||
"\n",
|
||||
"=== Pol2 ===\n",
|
||||
" True: p0=2.0000 p1=-0.5000 p2=0.3000\n",
|
||||
" Fitted: p0=2.1391 p1=-0.8442 p2=0.3383\n",
|
||||
" Chi2: [34.11224393]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"m1 = Pol1()\n",
|
||||
"m2 = Pol2()\n",
|
||||
" \n",
|
||||
"res1 = m1.fit(x, y_pol1_noisy)\n",
|
||||
"res2 = m2.fit(x, y_pol2_noisy)\n",
|
||||
"\n",
|
||||
"p1 = res1['par']\n",
|
||||
"print(\"=== Pol1 ===\")\n",
|
||||
"print(f\" True: p0={true_pol1[0]:.4f} p1={true_pol1[1]:.4f}\")\n",
|
||||
"print(f\" Fitted: p0={p1[0]:.4f} p1={p1[1]:.4f}\")\n",
|
||||
"print(f\" Chi2: {res1['chi2']}\")\n",
|
||||
"print()\n",
|
||||
"\n",
|
||||
"p2 = res2['par']\n",
|
||||
"print(\"=== Pol2 ===\")\n",
|
||||
"print(f\" True: p0={true_pol2[0]:.4f} p1={true_pol2[1]:.4f} p2={true_pol2[2]:.4f}\")\n",
|
||||
"print(f\" Fitted: p0={p2[0]:.4f} p1={p2[1]:.4f} p2={p2[2]:.4f}\")\n",
|
||||
"print(f\" Chi2: {res2['chi2']}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "7e185144-3b72-41f4-80d0-3c3504e48bba",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Plot"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"id": "9a0b3292-7c57-4483-aecc-7ef683ff0b62",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAHqCAYAAADVi/1VAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAADH/0lEQVR4nOzde3zO9f/H8cfn2uHaeYwdMHNIq2zoQAmFvo3kVDmmRDoocqyUjhQp5ZBIB/0ckkqKjpgUOuAbUbHChGnMNFw72Obars/vj4uLfZ3Zdl3bnvfbza193p/39ble117W3l6f9/v9MUzTNBERERERERERESlFFncHICIiIiIiIiIiFY+KUiIiIiIiIiIiUupUlBIRERERERERkVKnopSIiIiIiIiIiJQ6FaVERERERERERKTUqSglIiIiIiIiIiKlTkUpEREREREREREpdSpKiYiIiIiIiIhIqVNRSkRERERERERESp2KUiLi0WbNmoVhGK4/3t7eREdHc++995Kamnpe12rVqhWtWrUq0jZnzhx69uzJZZddhsVioXbt2sUXvIiIiIgblOT4ae/evTzzzDNcf/31VK1alZCQEK655hreeecdCgsLi/mTiEh55+3uAEREzsXMmTO5/PLLyc3NZdWqVYwbN46VK1fyxx9/EBgYeMHXff/990lLS+Paa6/F4XBgt9uLMWoRERER9ymJ8dP69euZM2cO99xzD88++yw+Pj4sXryYhx9+mDVr1vB///d/xfwpRKQ8U1FKRMqE+Ph4GjduDEDr1q0pLCzkxRdfZNGiRdx1110XfN2lS5disTgnjXbo0IFNmzYVS7wiIiIi7lYS46fmzZuzfft2fHx8XG0JCQkcOXKEadOmMXr0aGrWrFks8YtI+afleyJSJjVt2hSAXbt2kZeXx8iRI6lTpw6+vr7UqFGDgQMHcujQobNe51hBSkRERKS8K47xU+XKlYsUpI659tprAfjnn3+KPW4RKb80U0pEyqTk5GQAwsPDue2221i+fDkjR47khhtu4Pfff+f5559n9erVrF69GqvV6uZoRURERNyvJMdP3333Hd7e3sTGxpZE6CJSTqkoJSJlQmFhIQUFBeTl5bFy5UrGjBlDcHAwISEhLF26lPHjx/P4448DzinkNWvWpEePHsyZM4cHHnjAzdGLiIiIlL7SGj8lJiby/vvvM2TI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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 1200x500 with 2 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))\n",
|
||||
" \n",
|
||||
"# Pol1\n",
|
||||
"ax1.plot(x, y_pol1_noisy, 'o', ms=4, alpha=0.6, label='data')\n",
|
||||
"ax1.plot(x, y_pol1, 'k--', label='truth')\n",
|
||||
"ax1.plot(x, m1(x, res1['par']), 'r-', lw=2, label='fit')\n",
|
||||
"ax1.set_title('Pol1')\n",
|
||||
"ax1.legend()\n",
|
||||
"ax1.grid(alpha=0.3)\n",
|
||||
" \n",
|
||||
"# Pol2\n",
|
||||
"ax2.plot(x, y_pol2_noisy, 'o', ms=4, alpha=0.6, label='data')\n",
|
||||
"ax2.plot(x, y_pol2, 'k--', label='truth')\n",
|
||||
"ax2.plot(x, m2(x, res2['par']), 'r-', lw=2, label='fit')\n",
|
||||
"ax2.set_title('Pol2')\n",
|
||||
"ax2.legend()\n",
|
||||
"ax2.grid(alpha=0.3)\n",
|
||||
" \n",
|
||||
"fig.tight_layout()\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e694c18a-a203-4132-a472-c93c4d3ce853",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.12.5"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "efef8e20-6571-4561-8f0b-6048b57907de",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"import sys\n",
|
||||
"sys.path.insert(0, '/home/ferjao_k/sw/aare/build')\n",
|
||||
"from aare import Pol1, Pol2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8449f9e9-59ee-4194-b477-d014b8efc93b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Ground truth\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "35772e2c-37c6-4986-a9c0-7dca4a034827",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"x = np.linspace(0, 10, 50)\n",
|
||||
" \n",
|
||||
"# Pol1: y = 3.0 + 1.5*x\n",
|
||||
"true_pol1 = [3.0, 1.5]\n",
|
||||
"y_pol1 = true_pol1[0] + true_pol1[1] * x\n",
|
||||
"y_pol1_noisy = y_pol1 + np.random.default_rng(42).normal(0, 0.5, x.size)\n",
|
||||
" \n",
|
||||
"# Pol2: y = 2.0 - 0.5*x + 0.3*x^2\n",
|
||||
"true_pol2 = [2.0, -0.5, 0.3]\n",
|
||||
"y_pol2 = true_pol2[0] + true_pol2[1] * x + true_pol2[2] * x**2\n",
|
||||
"y_pol2_noisy = y_pol2 + np.random.default_rng(7).normal(0, 1.0, x.size)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a318ab93-fe18-4798-9ddb-6ffc2c2e3875",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Fit with error estimation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"id": "06c8fddb-56d9-4f84-8b21-4ffd8b7bd26f",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"=== Pol1 ===\n",
|
||||
" True: p0=3.0000 p1=1.5000\n",
|
||||
" Fitted: p0=2.9325 p1=1.5226\n",
|
||||
" Chi2: [7.00870822]\n",
|
||||
"\n",
|
||||
"=== Pol2 ===\n",
|
||||
" True: p0=2.0000 p1=-0.5000 p2=0.3000\n",
|
||||
" Fitted: p0=2.1391 p1=-0.8442 p2=0.3383\n",
|
||||
" Chi2: [34.11224393]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"m1 = Pol1()\n",
|
||||
"m2 = Pol2()\n",
|
||||
" \n",
|
||||
"res1 = m1.fit(x, y_pol1_noisy)\n",
|
||||
"res2 = m2.fit(x, y_pol2_noisy)\n",
|
||||
"\n",
|
||||
"p1 = res1['par']\n",
|
||||
"print(\"=== Pol1 ===\")\n",
|
||||
"print(f\" True: p0={true_pol1[0]:.4f} p1={true_pol1[1]:.4f}\")\n",
|
||||
"print(f\" Fitted: p0={p1[0]:.4f} p1={p1[1]:.4f}\")\n",
|
||||
"print(f\" Chi2: {res1['chi2']}\")\n",
|
||||
"print()\n",
|
||||
"\n",
|
||||
"p2 = res2['par']\n",
|
||||
"print(\"=== Pol2 ===\")\n",
|
||||
"print(f\" True: p0={true_pol2[0]:.4f} p1={true_pol2[1]:.4f} p2={true_pol2[2]:.4f}\")\n",
|
||||
"print(f\" Fitted: p0={p2[0]:.4f} p1={p2[1]:.4f} p2={p2[2]:.4f}\")\n",
|
||||
"print(f\" Chi2: {res2['chi2']}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "7e185144-3b72-41f4-80d0-3c3504e48bba",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Plot"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"id": "9a0b3292-7c57-4483-aecc-7ef683ff0b62",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png":
|
||||
"iVBORw0KGgoAAAANSUhEUgAABKUAAAHqCAYAAADVi/1VAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAADH/0lEQVR4nOzde3zO9f/H8cfn2uHaeYwdMHNIq2zoQAmFvo3kVDmmRDoocqyUjhQp5ZBIB/0ckkqKjpgUOuAbUbHChGnMNFw72Obars/vj4uLfZ3Zdl3bnvfbza193p/39ble117W3l6f9/v9MUzTNBERERERERERESlFFncHICIiIiIiIiIiFY+KUiIiIiIiIiIiUupUlBIRERERERERkVKnopSIiIiIiIiIiJQ6FaVERERERERERKTUqSglIiIiIiIiIiKlTkUpEREREREREREpdSpKiYiIiIiIiIhIqVNRSkRERERERERESp2KUiLi0WbNmoVhGK4/3t7eREdHc++995Kamnpe12rVqhWtWrUq0jZnzhx69uzJZZddhsVioXbt2sUXvIiIiIgblOT4ae/evTzzzDNcf/31VK1alZCQEK655hreeecdCgsLi/mTiEh55+3uAEREzsXMmTO5/PLLyc3NZdWqVYwbN46VK1fyxx9/EBgYeMHXff/990lLS+Paa6/F4XBgt9uLMWoRERER9ymJ8dP69euZM2cO99xzD88++yw+Pj4sXryYhx9+mDVr1vB///d/xfwpRKQ8U1FKRMqE+Ph4GjduDEDr1q0pLCzkxRdfZNGiRdx1110XfN2lS5disTgnjXbo0IFNmzYVS7wiIiIi7lYS46fmzZuzfft2fHx8XG0JCQkcOXKEadOmMXr0aGrWrFks8YtI+afleyJSJjVt2hSAXbt2kZeXx8iRI6lTpw6+vr7UqFGDgQMHcujQobNe51hBSkRERKS8K47xU+XKlYsUpI659tprAfjnn3+KPW4RKb80U0pEyqTk5GQAwsPDue2221i+fDkjR47khhtu4Pfff+f5559n9erVrF69GqvV6uZoRURERNyvJMdP3333Hd7e3sTGxpZE6CJSTqkoJSJlQmFhIQUFBeTl5bFy5UrGjBlDcHAwISEhLF26lPHjx/P4448DzinkNWvWpEePHsyZM4cHHnjAzdGLiIiIlL7SGj8lJiby/vvvM2TI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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 1200x500 with 2 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))\n",
|
||||
" \n",
|
||||
"# Pol1\n",
|
||||
"ax1.plot(x, y_pol1_noisy, 'o', ms=4, alpha=0.6, label='data')\n",
|
||||
"ax1.plot(x, y_pol1, 'k--', label='truth')\n",
|
||||
"ax1.plot(x, m1(x, res1['par']), 'r-', lw=2, label='fit')\n",
|
||||
"ax1.set_title('Pol1')\n",
|
||||
"ax1.legend()\n",
|
||||
"ax1.grid(alpha=0.3)\n",
|
||||
" \n",
|
||||
"# Pol2\n",
|
||||
"ax2.plot(x, y_pol2_noisy, 'o', ms=4, alpha=0.6, label='data')\n",
|
||||
"ax2.plot(x, y_pol2, 'k--', label='truth')\n",
|
||||
"ax2.plot(x, m2(x, res2['par']), 'r-', lw=2, label='fit')\n",
|
||||
"ax2.set_title('Pol2')\n",
|
||||
"ax2.legend()\n",
|
||||
"ax2.grid(alpha=0.3)\n",
|
||||
" \n",
|
||||
"fig.tight_layout()\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e694c18a-a203-4132-a472-c93c4d3ce853",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.12.5"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -1,386 +1,397 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "efef8e20-6571-4561-8f0b-6048b57907de",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import time\n",
|
||||
"import random\n",
|
||||
"import numpy as np\n",
|
||||
"np.set_printoptions(suppress=True, precision=6)\n",
|
||||
"\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"from scipy.special import erf\n",
|
||||
"\n",
|
||||
"import sys\n",
|
||||
"# sys.path.insert(0, '/home/ferjao_k/sw/aare/build')\n",
|
||||
"sys.path.insert(0, '/home/kferjaoui/sw/aare/build')\n",
|
||||
"\n",
|
||||
"from aare import fit_scurve, fit_scurve2 # lmfit\n",
|
||||
"from aare import RisingScurve, FallingScurve, fit # minuit2 (object based API)\n",
|
||||
"\n",
|
||||
"from pprint import pprint"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8449f9e9-59ee-4194-b477-d014b8efc93b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Model curves"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "35772e2c-37c6-4986-a9c0-7dca4a034827",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def scurve(x, p): # rising Scurve\n",
|
||||
" p0, p1, p2, p3, p4, p5 = p\n",
|
||||
" return (p0 + p1*x) + 0.5 *(1 + erf((x-p2) / (np.sqrt(2)*p3))) * (p4 + p5*(x-p2))\n",
|
||||
"\n",
|
||||
"def scurve2(x, p): #falling Scurve\n",
|
||||
" p0, p1, p2, p3, p4, p5 = p\n",
|
||||
" return (p0 + p1*x) + 0.5 *(1 - erf((x-p2) / (np.sqrt(2)*p3))) * (p4 + p5*(x-p2))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a318ab93-fe18-4798-9ddb-6ffc2c2e3875",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Generate data (1D)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "06c8fddb-56d9-4f84-8b21-4ffd8b7bd26f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"x = np.linspace(0,120, 121)\n",
|
||||
"\n",
|
||||
"rng = np.random.default_rng(42)\n",
|
||||
"0\n",
|
||||
"p_true_rising = np.array([100.0, 0.25, 60.0, 6.0, 120.0, 1.0])\n",
|
||||
"p_true_falling = np.array([100.0, 0.25, 60.0, 6.0, 120.0, -1.0])\n",
|
||||
"\n",
|
||||
"y_true_rising = scurve(x, p_true_rising)\n",
|
||||
"y_true_falling = scurve2(x, p_true_falling)\n",
|
||||
"\n",
|
||||
"noise_sigma = 4\n",
|
||||
"\n",
|
||||
"y_rising = y_true_rising + rng.normal(0, noise_sigma, size=x.shape)\n",
|
||||
"# y_err_r = np.full_like(x, noise_sigma)\n",
|
||||
"\n",
|
||||
"y_falling = y_true_falling + rng.normal(0, noise_sigma, size=x.shape)\n",
|
||||
"# y_err_f = np.full_like(x, noise_sigma)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "7e185144-3b72-41f4-80d0-3c3504e48bba",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Plot synthetic data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "9a0b3292-7c57-4483-aecc-7ef683ff0b62",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 1200x400 with 2 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"fig, ax = plt.subplots(1, 2, figsize=(12,4), sharex=True)\n",
|
||||
"\n",
|
||||
"ax[0].plot(x, y_true_rising, label=\"true\")\n",
|
||||
"ax[0].scatter(x, y_rising, s=12, label=\"noisy\")\n",
|
||||
"ax[0].set_title(\"Rising S-curve\")\n",
|
||||
"ax[0].legend()\n",
|
||||
"\n",
|
||||
"ax[1].plot(x, y_true_falling, label=\"true\")\n",
|
||||
"ax[1].scatter(x, y_falling, s=12, label=\"noisy\")\n",
|
||||
"ax[1].set_title(\"Falling S-curve\")\n",
|
||||
"ax[1].legend()\n",
|
||||
"\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "95c826d1-9223-4fb2-9ada-d9fc1acad2fb",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Fit the Rising S-curve"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "37d2fda4-40b8-4ea2-8f2c-6c3f2384d158",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"== Tuned fit settings ==\n",
|
||||
"max_calls : 500\n",
|
||||
"tolerance : 0.01\n",
|
||||
"compute_erros: True\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"== Results ==\n",
|
||||
"True rising params: [100. 0.25 60. 6. 120. 1. ]\n",
|
||||
"lmfit rising result: [ 99.467831 0.287017 60.078405 5.715461 117.257939 0.967234]\n",
|
||||
"minuit_grad (obj api ) rising result:\n",
|
||||
"{'par': array([ 99.288864, 0.291575, 60.091759, 5.675642, 117.08836 ,\n",
|
||||
" 0.963865]),\n",
|
||||
" 'par_err': array([2.853807, 0.104648, 0.764892, 0.930086, 8.309872, 0.191738]),\n",
|
||||
" 'chi2': array([7.28966])}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"res_r_lmfit = fit_scurve(x, y_rising)\n",
|
||||
"\n",
|
||||
"model_r = RisingScurve()\n",
|
||||
"# model_r.FixParameter(0, 100) # Fixed p0 = 100 (optimizer does not touch the value)\n",
|
||||
"model_r.SetParameter(4, 100) # Start value p4 = 100 \n",
|
||||
"print(\"== Tuned fit settings ==\")\n",
|
||||
"model_r.compute_errors = True\n",
|
||||
"model_r.max_calls = 500\n",
|
||||
"model_r.tolerance = 0.01\n",
|
||||
"print(f\"max_calls : {model_r.max_calls}\")\n",
|
||||
"print(f\"tolerance : {model_r.tolerance}\")\n",
|
||||
"print(f\"compute_erros: {model_r.compute_errors}\")\n",
|
||||
"print(\"\\n\")\n",
|
||||
"print(\"== Results ==\")\n",
|
||||
"res_r_munuit_obj = model_r.fit(x, y_rising, np.sqrt(y_rising))\n",
|
||||
"\n",
|
||||
"print(\"True rising params: \", p_true_rising)\n",
|
||||
"print(\"lmfit rising result: \", res_r_lmfit)\n",
|
||||
"print(\"minuit_grad (obj api ) rising result:\")\n",
|
||||
"pprint(res_r_munuit_obj, sort_dicts=False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "5ebf1328-954a-43ce-953b-c402fd7998f9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Fit the Falling S-curve"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "5ce22d2d-1adb-47d9-bf36-6cb535fa8b77",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"True falling params: [100. 0.25 60. 6. 120. -1. ]\n",
|
||||
"lmfit falling result: [101.734479 0.225786 60.251971 6.092915 118.476735 -0.998677]\n",
|
||||
"minuit_grad (obj api ) falling result\n",
|
||||
"{'par': array([101.734403, 0.225778, 60.251667, 6.093245, 118.479457,\n",
|
||||
" -0.998603]),\n",
|
||||
" 'chi2': array([1865.728851])}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"res_f_lmfit = fit_scurve2(x, y_falling)\n",
|
||||
"\n",
|
||||
"model_f = FallingScurve()\n",
|
||||
"model_f.SetParameter(2, 20) # set start p2 = 20\n",
|
||||
"model_f.SetParameter(4, 90) # set start p4 = 90\n",
|
||||
"model_f.SetParLimits(4, 80, 130)\n",
|
||||
"model_f.max_calls = 150 # this is limits the number of calls done by the minimizer (increasing the `max_calls` may help if the fit fails) \n",
|
||||
"res_f_munuit_obj = model_f.fit(x, y_falling)\n",
|
||||
"\n",
|
||||
"print(\"True falling params: \", p_true_falling)\n",
|
||||
"print(\"lmfit falling result: \", res_f_lmfit)\n",
|
||||
"print(\"minuit_grad (obj api ) falling result\")\n",
|
||||
"pprint(res_f_munuit_obj, sort_dicts=False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "fe72503a-fc77-4b17-9b17-b98055e2fc87",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png": "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 truncated
|
||||
"text/plain": [
|
||||
"<Figure size 1200x400 with 2 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"fig, ax = plt.subplots(1, 2, figsize=(12,4))\n",
|
||||
"\n",
|
||||
"# rising\n",
|
||||
"ax[0].plot(x, y_true_rising, label=\"true\")\n",
|
||||
"ax[0].scatter(x, y_rising, s=12, label=\"data\")\n",
|
||||
"ax[0].scatter(x, scurve(x, res_r_lmfit[:6]), s=20, marker=\"x\", label=\"lmfit\")\n",
|
||||
"ax[0].plot(x, model_r(x, res_r_munuit_obj['par']), linewidth=1, color=\"green\", label=\"minuit\")\n",
|
||||
"ax[0].set_title(\"Rising S-curve fits\")\n",
|
||||
"ax[0].legend()\n",
|
||||
"\n",
|
||||
"# falling\n",
|
||||
"ax[1].plot(x, y_true_falling, label=\"true\")\n",
|
||||
"ax[1].scatter(x, y_falling, s=12, label=\"data\")\n",
|
||||
"ax[1].scatter(x, scurve2(x, res_f_lmfit[:6]), s=20, marker=\"x\", label=\"lmfit\")\n",
|
||||
"ax[1].plot(x, model_f(x, res_f_munuit_obj['par']), linewidth=1, color=\"green\", label=\"minuit\")\n",
|
||||
"ax[1].set_title(\"Falling S-curve fits\")\n",
|
||||
"ax[1].legend()\n",
|
||||
"\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2c42ad91-fd59-47ba-b90d-8300f97eb27a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Quick error check"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"id": "3ba40e9a-0c64-4ef6-ba90-b1116f99b862",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Rising abs error lmfit : [0.532169 0.037017 0.078405 0.284539 2.742061 0.032766]\n",
|
||||
"Rising abs error minuit_grad: [0.711136 0.041575 0.091759 0.324358 2.91164 0.036135]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Falling abs error lmfit : [1.734479 0.024214 0.251971 0.092915 1.523265 0.001323]\n",
|
||||
"Falling abs error minuit_grad: [1.734403 0.024222 0.251667 0.093245 1.520543 0.001397]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(\"Rising abs error lmfit : \", np.abs(res_r_lmfit[:6] - p_true_rising))\n",
|
||||
"print(\"Rising abs error minuit_grad: \", np.abs(res_r_munuit_obj['par'] - p_true_rising))\n",
|
||||
"print(\"\\n\")\n",
|
||||
"print(\"Falling abs error lmfit : \", np.abs(res_f_lmfit[:6] - p_true_falling))\n",
|
||||
"print(\"Falling abs error minuit_grad: \", np.abs(res_f_munuit_obj['par'] - p_true_falling))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c9bbabfd-e24e-43ec-8622-983b3757d7a9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Benchmark"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"id": "dc0b52b6-9fc3-453d-b6eb-e325a2b8342e",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Rising lmfit : 0.445 ms\n",
|
||||
"Rising minuit2 : 0.322 ms\n",
|
||||
"\n",
|
||||
"Falling lmfit : 0.392 ms\n",
|
||||
"Falling minuit2 : 0.309 ms\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def bench(fn, n_repeats=200):\n",
|
||||
" # warmup\n",
|
||||
" for _ in range(3):\n",
|
||||
" fn()\n",
|
||||
"\n",
|
||||
" t0 = time.perf_counter()\n",
|
||||
" for _ in range(n_repeats):\n",
|
||||
" res = fn()\n",
|
||||
" t1 = time.perf_counter()\n",
|
||||
" return res, (t1 - t0) / n_repeats\n",
|
||||
"\n",
|
||||
"model_rising = RisingScurve()\n",
|
||||
"model_falling = FallingScurve()\n",
|
||||
"\n",
|
||||
"res_r_lmfit, t_r_lmfit = bench(lambda: fit_scurve(x, y_rising))\n",
|
||||
"res_r_minuit, t_r_minuit_grad = bench(lambda: model_rising.fit(x, y_rising))\n",
|
||||
"\n",
|
||||
"res_f_lmfit, t_f_lmfit = bench(lambda: fit_scurve2(x, y_falling))\n",
|
||||
"res_f_minuit, t_f_minuit_grad = bench(lambda: model_falling.fit(x, y_falling))\n",
|
||||
"\n",
|
||||
"print(f\"Rising lmfit : {1e3*t_r_lmfit:.3f} ms\")\n",
|
||||
"print(f\"Rising minuit2 : {1e3*t_r_minuit_grad:.3f} ms\")\n",
|
||||
"print()\n",
|
||||
"print(f\"Falling lmfit : {1e3*t_f_lmfit:.3f} ms\")\n",
|
||||
"print(f\"Falling minuit2 : {1e3*t_f_minuit_grad:.3f} ms\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e694c18a-a203-4132-a472-c93c4d3ce853",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.12.5"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "efef8e20-6571-4561-8f0b-6048b57907de",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import time\n",
|
||||
"import random\n",
|
||||
"import numpy as np\n",
|
||||
"np.set_printoptions(suppress=True, precision=6)\n",
|
||||
"\n",
|
||||
"import matplotlib.pyplot as plt\n",
|
||||
"from scipy.special import erf\n",
|
||||
"\n",
|
||||
"import sys\n",
|
||||
"sys.path.insert(0, '/home/ferjao_k/sw/aare/build')\n",
|
||||
"\n",
|
||||
"from aare import fit_scurve, fit_scurve2 # lmfit\n",
|
||||
"from aare import RisingScurve, FallingScurve, fit # minuit2 (object based API)\n",
|
||||
"\n",
|
||||
"from pprint import pprint"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "8449f9e9-59ee-4194-b477-d014b8efc93b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Model curves"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "35772e2c-37c6-4986-a9c0-7dca4a034827",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def scurve(x, p): # rising Scurve\n",
|
||||
" p0, p1, p2, p3, p4, p5 = p\n",
|
||||
" return (p0 + p1*x) + 0.5 *(1 + erf((x-p2) / (np.sqrt(2)*p3))) * (p4 + p5*(x-p2))\n",
|
||||
"\n",
|
||||
"def scurve2(x, p): #falling Scurve\n",
|
||||
" p0, p1, p2, p3, p4, p5 = p\n",
|
||||
" return (p0 + p1*x) + 0.5 *(1 - erf((x-p2) / (np.sqrt(2)*p3))) * (p4 + p5*(x-p2))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "a318ab93-fe18-4798-9ddb-6ffc2c2e3875",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Generate data (1D)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "06c8fddb-56d9-4f84-8b21-4ffd8b7bd26f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"x = np.linspace(0,120, 121)\n",
|
||||
"\n",
|
||||
"rng = np.random.default_rng(42)\n",
|
||||
"0\n",
|
||||
"p_true_rising = np.array([100.0, 0.25, 60.0, 6.0, 120.0, 1.0])\n",
|
||||
"p_true_falling = np.array([100.0, 0.25, 60.0, 6.0, 120.0, -1.0])\n",
|
||||
"\n",
|
||||
"y_true_rising = scurve(x, p_true_rising)\n",
|
||||
"y_true_falling = scurve2(x, p_true_falling)\n",
|
||||
"\n",
|
||||
"noise_sigma = 4\n",
|
||||
"\n",
|
||||
"y_rising = y_true_rising + rng.normal(0, noise_sigma, size=x.shape)\n",
|
||||
"# y_err_r = np.full_like(x, noise_sigma)\n",
|
||||
"\n",
|
||||
"y_falling = y_true_falling + rng.normal(0, noise_sigma, size=x.shape)\n",
|
||||
"# y_err_f = np.full_like(x, noise_sigma)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "7e185144-3b72-41f4-80d0-3c3504e48bba",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Plot synthetic data"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "9a0b3292-7c57-4483-aecc-7ef683ff0b62",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png":
|
||||
"iVBORw0KGgoAAAANSUhEUgAAA9oAAAF0CAYAAADcnkHwAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAACSjElEQVR4nOzdeXwTZf4H8M8kbdP7phcNpSBHS7lBCogUQS4BURBUUFFg/SmwssDqIiqIIh67HosrqwsCUhBPQAVB7kPkKmdpuXvSC3qlV9I0md8fITFpkp5p0+Pzfr2izWQyeSYkmfnO8zzfryCKoggiIiIiIiIisgmJvRtARERERERE1JIw0CYiIiIiIiKyIQbaRERERERERDbEQJuIiIiIiIjIhhhoExEREREREdkQA20iIiIiIiIiG2KgTURERERERGRDDLSJiIiIiIiIbIiBNhEREREREZENMdAmsmL9+vUQBMFwc3BwQHBwMB5//HFcu3bNbP2YmBjExMTU6jUOHjwIQRBw8OBB2zS6lhITE/HUU0+hQ4cOcHZ2hr+/P/r06YO5c+dCoVDYpU1ERESNofJx3vi2aNGiGm8nOTkZgiBg/fr1ZttOTk42LJsxYwbat29vux2oBVEUsWXLFgwZMgQBAQFwdnZGaGgoRo0ahTVr1tilTUQtnYO9G0DU1K1btw5du3aFUqnE77//jhUrVuDAgQO4fPkyfHx8DOt99tlntd52nz598McffyAyMtKWTa6Rs2fPYvDgwYiIiMAbb7yB9u3b486dOzh//jy2bNmCRYsWwdPTs9HbRURE1Jj0x3ljISEhNn+d119/HS+99JLNt1sTixcvxnvvvYfZs2fj73//Ozw8PJCSkoL9+/dj+/btmDVrll3aRdSSMdAmqkZUVBT69esHQNdrrdFosHTpUmzbtg3PPvusYb26BMuenp6Ijo62WVtr4+OPP4ZEIsHBgwfh4eFhWD558mS89dZbEEXRLu0yJooilEolXFxc7N0UIiJqoYyP8w2pY8eODf4alpSVleHjjz/G008/jS+++MLksRkzZkCr1dqlXZWVlZXB2dkZgiDYuylENsGh40S1pD8YZ2dnmyy3NHR89erV6NmzJ9zd3eHh4YGuXbvi1VdfNTxuaej4jBkz4O7ujuvXr2Ps2LFwd3eHXC7HwoULoVKpTLafnp6OyZMnw8PDA97e3pg2bRpOnTplNoTNktzcXHh6esLd3d3i4zU90J04cQLjx4+Hn58fnJ2d0bFjR8yfP99kfywNlVu2bJnZawiCgLlz5+K///0vIiIiIJPJsGbNGgQEBOCpp54y20ZBQQFcXFywYMECwzKFQoFFixYhPDwcTk5OaNu2LebPn4+SkpIa7Q8REREAXL9+Hc8++yw6deoEV1dXtG3bFuPHj8fFixfrtD1Lx0P9cW/jxo2IiIiAq6srevbsiV9++cXs+du3b0ePHj0gk8nQoUMHfPLJJxaPpZWVlJRApVIhODjY4uMSSc3CAa1Wi1WrVqFXr15wcXGBt7c3oqOj8dNPP5nsz7Jly8ye2759e8yYMcNwXz+0/rfffsNzzz2HNm3awNXVFd988w0EQcC+ffvMtrF69WoIgoALFy4Ylp0+fRoTJkyAr68vnJ2d0bt3b3z77bc12h+ihsYebaJaSkpKAgB07ty5yvW2bNmCF198EfPmzcM///lPSCQSXL9+HQkJCdW+hlqtxoQJEzBz5kwsXLgQhw8fxltvvQUvLy+88cYbAHQHzmHDhiEvLw/vvfce7rnnHuzatQtTp06t0X4MHDgQO3bswLRp0/D888/j3nvvrXXP8e7duzF+/HhERETgww8/RLt27ZCcnIzffvutVtsxtm3bNhw5cgRvvPEGgoKCEBAQgKSkJPz3v//Ff/7zH5Ph7F9//TWUSqVhZEFpaSmGDh2K9PR0vPrqq+jRowcuXbqEN954AxcvXsTevXt5pZyIiExoNBpUVFSYLHNwcEBGRgb8/Pzw7rvvok2bNsjLy8OGDRswYMAAnD17Fl26dLHJ6+/YsQOnTp3C8uXL4e7ujvfffx+PPPIIrly5gg4dOgAAdu3ahUcffRT3338/vvnmG1RUVOCf//yn2UV/S/z9/XHPPffgs88+Q0BAAMaOHYsuXbrU+ng4Y8YMxMbGYubMmVi+fDmcnJxw5swZk3notfXcc8/hoYcewsaNG1FSUoJx48YhICAA69atw/Dhw03WXb9+Pfr06YMePXoAAA4cOIDRo0djwIAB+O9//wsvLy9s2bIFU6dORWlpqUlgT2QXIhFZtG7dOhGAePz4cVGtVotFRUXirl27xKCgIPH+++8X1Wq1yfpDhw4Vhw4darg/d+5c0dvbu8rXOHDggAhAPHDggGHZM888IwIQv/32W5N1x44dK3bp0sVw/z//+Y8IQPz1119N1nv++edFAOK6deuqfG2lUilOnDhRBCACEKVSqdi7d29xyZIlYk5OTpXP1evYsaPYsWNHsayszOo6zzzzjBgWFma2fOnSpWLlnyAAopeXl5iXl2ey/MKFCyIA8YsvvjBZfu+994p9+/Y13F+5cqUokUjEU6dOmaz3/fffiwDEnTt31mi/iIio5dMf5y3dKh/jRVEUKyoqxPLycrFTp07i3/72N8PypKQks+OufttJSUmGZZaOhwDEwMBAUaFQGJZlZWWJEolEXLlypWFZ//79RblcLqpUKsOyoqIi0c/Pz+xYasnJkyfFdu3aGfbPw8NDHDdunPjVV1+JWq222ucfPnxYBCAuWbKkyvUAiEuXLjVbHhYWJj7zzDOG+/r35+mnnzZbd8GCBaKLi4tYUFBgWJaQkCACEFetWmVY1rVrV7F3795m/1bjxo0Tg4ODRY1GU+1+ETUkDh0nqkZ0dDQcHR3h4eGB0aNHw8fHB9u3b4eDQ9UDQu69914UFBTgiSeewPbt23Hnzp0av6YgCBg/frzJsh49eiAlJcVw/9ChQ4Y2GXviiSdq9BoymQxbt25FQkICPvroIzz++OO4ffs2VqxYgYiICFy5cgWAbp50RUWFyQ0Arl69ihs3bmDmzJlwdnau8b5V54EHHjBJMgcA3bt3R9++fbFu3TrDssTERJw8eRLPPfecYdkvv/yCqKgo9OrVy6S9o0aNsmt2dyIiarq++uornDp1yuTm4OCAiooKvPPOO4iMjISTkxMcHBzg5OSEa9euITEx0WavP2zYMJNcKYGBgQgICDAc80tKSnD69GlMnDgRTk5OhvXc3d3NzhWs6d+/P65fv45du3bh1VdfxcCBA7Fv3z48/fTTmDBhgiEvi753X3/Tz9/+9ddfAQBz5syxyT7rTZo0yWzZc889h7KyMnzzzTeGZevWrYNMJsOTTz4JQDes//Lly5g2bRoAmLR57NixyMzMNJzHENkLA22iaugPwPv378fzzz+PxMTEGgWzTz31FL788kukpKRg0qRJCAgIwIABA7Bnz55qn+vq6moWvMpkMiiVSsP93NxcBAYGmj3X0rKqREREYP78+YiNjUVqaio+/PBD5Obm4vXXXwcAbNiwAY6OjiY3ALh9+zYAIDQ0tFavVx1rc8iee+45/PHHH7h8+TKAPw+6xv8W2dnZuHDhgll7PTw8IIpirS52EBFR6xAREYF+/fqZ3ABgwYIFeP311zFx4kT8/PPPOHHiBE6dOoWePXuirKzMZq/v5+dntkwmkxleIz8/H6Io1vuY7+joiFGjRmHFihXYvXs30tLSEBMTg19++cUQSA8fPtzk+Km/mH379m1IpVIEBQXVZRetsnTM79atG/r372+4uK7RaBAbG4uHH34Yvr6+AP7Mk7No0SKzY/6LL74IADzmk91xjjZRNfQHYEB31Vmj0WDNmjX4/vvvMXny5Cqf++yzz+LZZ59FSUkJDh8+jKVLl2LcuHG4evUqwsLC6tUuPz8/nDx50mx5VlZWnbcpCAL+9re/Yfny5YiPjwcAjB8/HqdOnTJbt02bNgB0Cdmq4uzsbJbEDbB+ALQ2Z+yJJ57AggULsH79eqxYsQIbN27ExIkTTXq//f394eLigi+//NLiNvz9/atsKxERkV5sbCyefvppvPPOOybL79y5A29v70Zrh4+PDwRBsDgfuz7HfD8/P8yfPx8HDx5EfHw8xo4di88//xxFRUWGdfTHzTZt2kCj0SArK8vqBXFAd4HA0jE/NzfX4vrWjvnPPvssXnzxRSQmJuLmzZvIzMw0qfSib9fixYvx6KOPWtyGrebQE9UVe7SJaun999+Hj48P3njjjRqXxHBzc8OYMWOwZMkSlJeX49KlS/Vux9ChQ1FUVGS4Cq23ZcuWGj0/MzPT4vKMjAwoFApDDVE/Pz+LV/o7d+6Mjh074ssvv7R4UNVr3749cnJyTE4QysvLsXv37hq1U8/HxwcTJ07EV199hV9++QVZWVkmw8YBYNy4cbhx44bFNvfr189i9nMiIiJLBEGATCYzWbZjxw7cunWrUdvh5uaGfv36Ydu2bSgvLzcsLy4utpidvDK1Wm010NUPgdcf87t06WLxuDlmzBgAuszfVWnfvr1JVnAA2L9/P4qLi6ttp7EnnngCzs7OWL9+PdavX4+2bdti5MiRhse7dOmCTp064fz58xaP9/369TMZjk9kD+zRJqolHx8fLF68GC+//DI2b96M6dOnW1xv9uzZcHFxweDBgxEcHIysrCysXLkSXl5e6N+/f73b8cwzz+Cjjz7C9OnT8fbbb+Oee+7Br7/+aghgqyvX8Ze//AUFBQWYNGkSoqKiIJVKcfnyZXz00UeQSCR45ZVXqm3Df/7zH4wfPx7R0dH429/+hnbt2iE1NRW7d+/Gpk2bAABTp07FG2+8gccffxx///vfoVQq8e9//xsajabW+/zcc8/hm2++wdy5cxEaGooRI0aYPD5//nz88MMPuP/++/G3v/0NPXr0gFarRWpqKn777TcsXLgQAwYMqPXrEhFR6zLine truncated
|
||||
"text/plain": [
|
||||
"<Figure size 1200x400 with 2 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"fig, ax = plt.subplots(1, 2, figsize=(12,4), sharex=True)\n",
|
||||
"\n",
|
||||
"ax[0].plot(x, y_true_rising, label=\"true\")\n",
|
||||
"ax[0].scatter(x, y_rising, s=12, label=\"noisy\")\n",
|
||||
"ax[0].set_title(\"Rising S-curve\")\n",
|
||||
"ax[0].legend()\n",
|
||||
"\n",
|
||||
"ax[1].plot(x, y_true_falling, label=\"true\")\n",
|
||||
"ax[1].scatter(x, y_falling, s=12, label=\"noisy\")\n",
|
||||
"ax[1].set_title(\"Falling S-curve\")\n",
|
||||
"ax[1].legend()\n",
|
||||
"\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "95c826d1-9223-4fb2-9ada-d9fc1acad2fb",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Fit the Rising S-curve"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"id": "37d2fda4-40b8-4ea2-8f2c-6c3f2384d158",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Paramter list of the Scurve:\n",
|
||||
"['p0', 'p1', 'mu', 'sigma', 'A', 'C']\n",
|
||||
"6 \n",
|
||||
"\n",
|
||||
"== Tuned fit settings ==\n",
|
||||
"max_calls : 500\n",
|
||||
"tolerance : 0.01\n",
|
||||
"compute_erros: True\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"== Results ==\n",
|
||||
"True rising params: [100. 0.25 60. 6. 120. 1. ]\n",
|
||||
"lmfit rising result: [ 99.467831 0.287017 60.078405 5.715461 117.257939 0.967234]\n",
|
||||
"minuit_grad (obj api ) rising result:\n",
|
||||
"{'par': array([100. , 0.269137, 60.050193, 5.729932, 117.777635,\n",
|
||||
" 0.984073]),\n",
|
||||
" 'par_err': array([1. , 0.054406, 0.747753, 0.909864, 7.887499, 0.174058]),\n",
|
||||
" 'chi2': array([7.351743])}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"res_r_lmfit = fit_scurve(x, y_rising)\n",
|
||||
"\n",
|
||||
"model_r = RisingScurve()\n",
|
||||
"print(\"Paramter list of the Scurve:\")\n",
|
||||
"# print(model_r.GetParNames())\n",
|
||||
"print(model_r.par_names)\n",
|
||||
"print(model_r.n_par, '\\n')\n",
|
||||
"\n",
|
||||
"model_r.FixParameter('p0', 100) # Fixed p0 = 100 (optimizer does not touch the value)\n",
|
||||
"model_r.SetParameter('A', 100) # Start value A = 100\n",
|
||||
"\n",
|
||||
"print(\"== Tuned fit settings ==\")\n",
|
||||
"model_r.compute_errors = True\n",
|
||||
"model_r.max_calls = 500\n",
|
||||
"model_r.tolerance = 0.01\n",
|
||||
"print(f\"max_calls : {model_r.max_calls}\")\n",
|
||||
"print(f\"tolerance : {model_r.tolerance}\")\n",
|
||||
"print(f\"compute_erros: {model_r.compute_errors}\")\n",
|
||||
"print(\"\\n\")\n",
|
||||
"print(\"== Results ==\")\n",
|
||||
"res_r_munuit_obj = model_r.fit(x, y_rising, np.sqrt(y_rising))\n",
|
||||
"\n",
|
||||
"print(\"True rising params: \", p_true_rising)\n",
|
||||
"print(\"lmfit rising result: \", res_r_lmfit)\n",
|
||||
"print(\"minuit_grad (obj api ) rising result:\")\n",
|
||||
"pprint(res_r_munuit_obj, sort_dicts=False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "5ebf1328-954a-43ce-953b-c402fd7998f9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Fit the Falling S-curve"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"id": "5ce22d2d-1adb-47d9-bf36-6cb535fa8b77",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"True falling params: [100. 0.25 60. 6. 120. -1. ]\n",
|
||||
"lmfit falling result: [101.73448 0.225786 60.251971 6.092915 118.476735 -0.998677]\n",
|
||||
"minuit_grad (obj api ) falling result\n",
|
||||
"{'par': array([101.741754, 0.225723, 60.251604, 6.092887, 118.473268,\n",
|
||||
" -0.998565]),\n",
|
||||
" 'chi2': array([1865.728797])}\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"res_f_lmfit = fit_scurve2(x, y_falling)\n",
|
||||
"\n",
|
||||
"model_f = FallingScurve()\n",
|
||||
"model_f.SetParameter(2, 20) # set start p2 = 20\n",
|
||||
"model_f.SetParameter(4, 90) # set start p4 = 90\n",
|
||||
"model_f.SetParLimits(4, 80, 130)\n",
|
||||
"model_f.max_calls = 150 # this is limits the number of calls done by the minimizer (increasing the `max_calls` may help if the fit fails) \n",
|
||||
"res_f_munuit_obj = model_f.fit(x, y_falling)\n",
|
||||
"\n",
|
||||
"print(\"True falling params: \", p_true_falling)\n",
|
||||
"print(\"lmfit falling result: \", res_f_lmfit)\n",
|
||||
"print(\"minuit_grad (obj api ) falling result\")\n",
|
||||
"pprint(res_f_munuit_obj, sort_dicts=False)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"id": "fe72503a-fc77-4b17-9b17-b98055e2fc87",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"image/png":
|
||||
"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p06duuR9appGmzZt8i2rVasWhw4d8jxft26dp015Pfnkk5e0D7PZzMKFC9m5cyeTJk3iiSee4OTJk4wdO5aqVauyZ88ewD1P2uFw5HsA7N27l3///ZdevXrh5eV1ycd2MQ888EC+JHMANWvW5K677mLmzJmeZbt27eKPP/6gZ8+enmU//vgjNWrU4M4778zX3hYtWly37O533303sbGxvP3222zcuBG73X7N9ymEEOLKzZ49m02bNuV7GAwGHA4H77zzDtWqVcNkMmEwGDCZTOzbt49du3YV2f6bNm2aL1dKREQE4eHhnnN+ZmYmf/75J+3atcNkMnnW8/PzO+9aoTD16tVj//79LF26lDfeeIMGDRqwatUqunXrxqOPPurJy5Lbu5/7yJ2//fPPPwPQr1+/IjnmXB06dDhvWc+ePcnOzmb+/PmeZTNnzsRsNtOlSxfAPax/9+7dPPXUUwD52tyqVSvi4+M91zHXyp133onJZKJPnz7MmjWLAwcOXNP9iVuPBNrippd7Al69ejXPPfccu3btuqRg9umnn2bGjBkcOnSIDh06EB4ezj333MOKFSsu+l4fH5/zglez2YzVavU8P336NBEREee9t6BlF1K1alUGDhzInDlzOHz4MBMnTuT06dO8+eabAMyaNQuj0ZjvAe65yECBw6uvRmFzyHr27Mlvv/3G7t27gbMn3bw/ixMnTrBt27bz2muxWFBKXdbNjis1f/58unfvzvTp02nQoAHBwcF069aNhISEa75vIYQQl69q1arUrVs33wNg0KBBvPnmm7Rr147Fixfz+++/s2nTJu644w6ys7OLbP8hISHnLTObzZ59JCcno5S66nO+0WikRYsWjB07lmXLlnHkyBGaNGnCjz/+6AmkH3zwwXznz9yb2SdPnkSv1xMZGXklh1iogs751atXp169ep6b606nkzlz5tC2bVuCg4OBs3lyhgwZct45v2/fvgDX/JxfsWJFVq5cSXh4OP369aNixYpUrFiRyZMnX9P9iluHzNEWN73cEzC47zo7nU6mT5/OggUL6Nix4wXf+8wzz/DMM8+QmZnJL7/8wsiRI2ndujV79+4lJibmqtoVEhLCH3/8cd7yqwnoNE3j5ZdfZsyYMZ4M3G3atGHTpk3nrZs7J/no0aMX3KaXl9d5Sdyg8BNgYXPGnnzySQYNGkRsbCxjx47liy++oF27dvl6v0NDQ/H29mbGjBkFbiM0NPSCbS0KoaGhfPDBB3zwwQccPnyYH374gddff53ExESWLl16zfcvhBCiaMyZM4du3brxzjvv5Ft+6tSp61rmKSgoCE3TCpyPfTXn/JCQEAYOHMjatWvZvn07rVq14pNPPiE9Pd2zTuLine truncated
|
||||
"text/plain": [
|
||||
"<Figure size 1200x400 with 2 Axes>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"fig, ax = plt.subplots(1, 2, figsize=(12,4))\n",
|
||||
"\n",
|
||||
"# rising\n",
|
||||
"ax[0].plot(x, y_true_rising, label=\"true\")\n",
|
||||
"ax[0].scatter(x, y_rising, s=12, label=\"data\")\n",
|
||||
"ax[0].scatter(x, scurve(x, res_r_lmfit[:6]), s=20, marker=\"x\", label=\"lmfit\")\n",
|
||||
"ax[0].plot(x, model_r(x, res_r_munuit_obj['par']), linewidth=1, color=\"green\", label=\"minuit\")\n",
|
||||
"ax[0].set_title(\"Rising S-curve fits\")\n",
|
||||
"ax[0].legend()\n",
|
||||
"\n",
|
||||
"# falling\n",
|
||||
"ax[1].plot(x, y_true_falling, label=\"true\")\n",
|
||||
"ax[1].scatter(x, y_falling, s=12, label=\"data\")\n",
|
||||
"ax[1].scatter(x, scurve2(x, res_f_lmfit[:6]), s=20, marker=\"x\", label=\"lmfit\")\n",
|
||||
"ax[1].plot(x, model_f(x, res_f_munuit_obj['par']), linewidth=1, color=\"green\", label=\"minuit\")\n",
|
||||
"ax[1].set_title(\"Falling S-curve fits\")\n",
|
||||
"ax[1].legend()\n",
|
||||
"\n",
|
||||
"plt.show()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "2c42ad91-fd59-47ba-b90d-8300f97eb27a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Quick error check"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"id": "3ba40e9a-0c64-4ef6-ba90-b1116f99b862",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Rising abs error lmfit : [0.532169 0.037017 0.078405 0.284539 2.742061 0.032766]\n",
|
||||
"Rising abs error minuit_grad: [0. 0.019137 0.050193 0.270068 2.222365 0.015927]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"Falling abs error lmfit : [1.73448 0.024214 0.251971 0.092915 1.523265 0.001323]\n",
|
||||
"Falling abs error minuit_grad: [1.741754 0.024277 0.251604 0.092887 1.526732 0.001435]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"print(\"Rising abs error lmfit : \", np.abs(res_r_lmfit[:6] - p_true_rising))\n",
|
||||
"print(\"Rising abs error minuit_grad: \", np.abs(res_r_munuit_obj['par'] - p_true_rising))\n",
|
||||
"print(\"\\n\")\n",
|
||||
"print(\"Falling abs error lmfit : \", np.abs(res_f_lmfit[:6] - p_true_falling))\n",
|
||||
"print(\"Falling abs error minuit_grad: \", np.abs(res_f_munuit_obj['par'] - p_true_falling))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "c9bbabfd-e24e-43ec-8622-983b3757d7a9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Benchmark"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"id": "dc0b52b6-9fc3-453d-b6eb-e325a2b8342e",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Rising lmfit : 0.334 ms\n",
|
||||
"Rising minuit2 : 0.239 ms\n",
|
||||
"\n",
|
||||
"Falling lmfit : 0.294 ms\n",
|
||||
"Falling minuit2 : 0.214 ms\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def bench(fn, n_repeats=200):\n",
|
||||
" # warmup\n",
|
||||
" for _ in range(3):\n",
|
||||
" fn()\n",
|
||||
"\n",
|
||||
" t0 = time.perf_counter()\n",
|
||||
" for _ in range(n_repeats):\n",
|
||||
" res = fn()\n",
|
||||
" t1 = time.perf_counter()\n",
|
||||
" return res, (t1 - t0) / n_repeats\n",
|
||||
"\n",
|
||||
"model_rising = RisingScurve()\n",
|
||||
"model_falling = FallingScurve()\n",
|
||||
"\n",
|
||||
"res_r_lmfit, t_r_lmfit = bench(lambda: fit_scurve(x, y_rising))\n",
|
||||
"res_r_minuit, t_r_minuit_grad = bench(lambda: model_rising.fit(x, y_rising))\n",
|
||||
"\n",
|
||||
"res_f_lmfit, t_f_lmfit = bench(lambda: fit_scurve2(x, y_falling))\n",
|
||||
"res_f_minuit, t_f_minuit_grad = bench(lambda: model_falling.fit(x, y_falling))\n",
|
||||
"\n",
|
||||
"print(f\"Rising lmfit : {1e3*t_r_lmfit:.3f} ms\")\n",
|
||||
"print(f\"Rising minuit2 : {1e3*t_r_minuit_grad:.3f} ms\")\n",
|
||||
"print()\n",
|
||||
"print(f\"Falling lmfit : {1e3*t_f_lmfit:.3f} ms\")\n",
|
||||
"print(f\"Falling minuit2 : {1e3*t_f_minuit_grad:.3f} ms\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e694c18a-a203-4132-a472-c93c4d3ce853",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.12.5"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+1
-7
@@ -4,11 +4,11 @@
|
||||
#include "aare/Models.hpp"
|
||||
#include "aare/utils/par.hpp"
|
||||
#include "aare/utils/task.hpp"
|
||||
#include <array>
|
||||
#include <lmcurve2.h>
|
||||
#include <lmfit.hpp>
|
||||
#include <thread>
|
||||
#include <type_traits>
|
||||
#include <array>
|
||||
|
||||
namespace aare {
|
||||
|
||||
@@ -97,8 +97,6 @@ NDArray<double, 3> fit_gaus(NDView<double, 1> x, NDView<double, 3> y,
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void fit_gaus(NDView<double, 1> x, NDView<double, 1> y, NDView<double, 1> y_err,
|
||||
NDView<double, 1> par_out, NDView<double, 1> par_err_out,
|
||||
double &chi2) {
|
||||
@@ -278,7 +276,6 @@ NDArray<double, 3> fit_pol1(NDView<double, 1> x, NDView<double, 3> y,
|
||||
|
||||
// ~~ S-CURVES ~~
|
||||
|
||||
|
||||
// - No error
|
||||
NDArray<double, 1> fit_scurve(NDView<double, 1> x, NDView<double, 1> y) {
|
||||
NDArray<double, 1> result = model::RisingScurve::estimate_par(x, y);
|
||||
@@ -371,8 +368,6 @@ void fit_scurve(NDView<double, 1> x, NDView<double, 3> y,
|
||||
|
||||
// SCURVE2 ---
|
||||
|
||||
|
||||
|
||||
// - No error
|
||||
NDArray<double, 1> fit_scurve2(NDView<double, 1> x, NDView<double, 1> y) {
|
||||
NDArray<double, 1> result = model::FallingScurve::estimate_par(x, y);
|
||||
@@ -463,5 +458,4 @@ void fit_scurve2(NDView<double, 1> x, NDView<double, 3> y,
|
||||
RunInParallel(process, tasks);
|
||||
}
|
||||
|
||||
|
||||
} // namespace aare
|
||||
@@ -199,8 +199,7 @@ std::optional<ROI> RawMasterFile::roi() const {
|
||||
}
|
||||
|
||||
if (m_rois->empty()) {
|
||||
throw std::runtime_error(LOCATION +
|
||||
"Zero ROIs in metadata.");
|
||||
throw std::runtime_error(LOCATION + "Zero ROIs in metadata.");
|
||||
}
|
||||
|
||||
if (m_rois.value().size() > 1) {
|
||||
|
||||
+22
-29
@@ -1,48 +1,41 @@
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
# Download catch2 if configured to do so
|
||||
if (AARE_FETCH_CATCH)
|
||||
FetchContent_Declare(
|
||||
Catch2
|
||||
GIT_SHALLOW TRUE
|
||||
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
|
||||
GIT_TAG v3.5.3
|
||||
)
|
||||
FetchContent_MakeAvailable(Catch2)
|
||||
if(AARE_FETCH_CATCH)
|
||||
FetchContent_Declare(
|
||||
Catch2
|
||||
GIT_SHALLOW TRUE
|
||||
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
|
||||
GIT_TAG v3.5.3)
|
||||
FetchContent_MakeAvailable(Catch2)
|
||||
else()
|
||||
# Otherwise look for installed catch2
|
||||
find_package(Catch2 3 REQUIRED)
|
||||
# Otherwise look for installed catch2
|
||||
find_package(Catch2 3 REQUIRED)
|
||||
endif()
|
||||
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${Catch2_SOURCE_DIR}/extras)
|
||||
|
||||
add_executable(tests test.cpp)
|
||||
target_link_libraries(tests PRIVATE Catch2::Catch2WithMain aare_core aare_compiler_flags)
|
||||
# target_compile_options(tests PRIVATE -fno-omit-frame-pointer -fsanitize=address)
|
||||
set_target_properties(tests PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
OUTPUT_NAME run_tests
|
||||
)
|
||||
target_link_libraries(tests PRIVATE Catch2::Catch2WithMain aare_core
|
||||
aare_compiler_flags)
|
||||
# target_compile_options(tests PRIVATE -fno-omit-frame-pointer
|
||||
# -fsanitize=address)
|
||||
set_target_properties(
|
||||
tests PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_NAME
|
||||
run_tests)
|
||||
|
||||
include(CTest)
|
||||
include(Catch)
|
||||
catch_discover_tests(tests)
|
||||
|
||||
set(TestSources
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test.cpp
|
||||
)
|
||||
target_sources(tests PRIVATE ${TestSources} )
|
||||
set(TestSources ${CMAKE_CURRENT_SOURCE_DIR}/test.cpp)
|
||||
target_sources(tests PRIVATE ${TestSources})
|
||||
|
||||
#Work around to remove, this is not the way to do it =)
|
||||
# Work around to remove, this is not the way to do it =)
|
||||
# target_link_libraries(tests PRIVATE aare_core aare_compiler_flags)
|
||||
|
||||
|
||||
#configure a header to pass test file paths
|
||||
# configure a header to pass test file paths
|
||||
get_filename_component(TEST_FILE_PATH ${PROJECT_SOURCE_DIR}/data ABSOLUTE)
|
||||
configure_file(test_config.hpp.in test_config.hpp)
|
||||
target_include_directories(tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
|
||||
|
||||
|
||||
target_include_directories(tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR})
|
||||
@@ -0,0 +1,4 @@
|
||||
[default.extend-words]
|
||||
aare = "aare"
|
||||
gaus = "gaus"
|
||||
ND = "ND"
|
||||
Reference in new issue
Block a user