xcoll 0.3.6__py3-none-any.whl → 0.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of xcoll might be problematic. Click here for more details.
- xcoll/__init__.py +13 -4
- xcoll/beam_elements/__init__.py +14 -6
- xcoll/beam_elements/absorber.py +41 -7
- xcoll/beam_elements/base.py +1202 -247
- xcoll/beam_elements/blowup.py +198 -0
- xcoll/beam_elements/elements_src/black_absorber.h +136 -0
- xcoll/beam_elements/elements_src/black_crystal.h +129 -0
- xcoll/beam_elements/elements_src/blowup.h +42 -0
- xcoll/beam_elements/elements_src/emittance_monitor.h +109 -0
- xcoll/beam_elements/{collimators_src → elements_src}/everest_block.h +59 -30
- xcoll/beam_elements/elements_src/everest_collimator.h +237 -0
- xcoll/beam_elements/elements_src/everest_crystal.h +280 -0
- xcoll/beam_elements/everest.py +65 -119
- xcoll/beam_elements/monitor.py +428 -0
- xcoll/colldb.py +276 -747
- xcoll/general.py +5 -5
- xcoll/headers/checks.h +1 -1
- xcoll/headers/particle_states.h +2 -2
- xcoll/initial_distribution.py +207 -0
- xcoll/install.py +179 -0
- xcoll/interaction_record/__init__.py +1 -0
- xcoll/interaction_record/interaction_record.py +298 -0
- xcoll/interaction_record/interaction_record_src/interaction_record.h +98 -0
- xcoll/{impacts → interaction_record}/interaction_types.py +11 -4
- xcoll/line_tools.py +82 -0
- xcoll/lossmap.py +219 -0
- xcoll/manager.py +2 -937
- xcoll/rf_sweep.py +1 -1
- xcoll/scattering_routines/everest/amorphous.h +232 -0
- xcoll/scattering_routines/everest/channeling.h +240 -0
- xcoll/scattering_routines/everest/crystal_parameters.h +137 -0
- xcoll/scattering_routines/everest/everest.h +11 -30
- xcoll/scattering_routines/everest/everest.py +13 -10
- xcoll/scattering_routines/everest/jaw.h +28 -197
- xcoll/scattering_routines/everest/materials.py +37 -15
- xcoll/scattering_routines/everest/multiple_coulomb_scattering.h +31 -10
- xcoll/scattering_routines/everest/nuclear_interaction.h +86 -0
- xcoll/scattering_routines/everest/properties.h +6 -1
- xcoll/scattering_routines/fluka/flukaio/lib/libFlukaIO64.a +0 -0
- xcoll/scattering_routines/geant4/collimasim/.git +1 -0
- xcoll/scattering_routines/geant4/collimasim/.gitignore +12 -0
- xcoll/scattering_routines/geant4/collimasim/.gitmodules +3 -0
- xcoll/scattering_routines/geant4/collimasim/CMakeLists.txt +26 -0
- xcoll/scattering_routines/geant4/collimasim/README.md +21 -0
- xcoll/scattering_routines/geant4/collimasim/docs/Makefile +20 -0
- xcoll/scattering_routines/geant4/collimasim/docs/make.bat +35 -0
- xcoll/scattering_routines/geant4/collimasim/docs/source/collimasim.rst +10 -0
- xcoll/scattering_routines/geant4/collimasim/docs/source/conf.py +59 -0
- xcoll/scattering_routines/geant4/collimasim/docs/source/index.rst +26 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.appveyor.yml +37 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.clang-format +19 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.clang-tidy +65 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.cmake-format.yaml +73 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.git +1 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/CODEOWNERS +9 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/CONTRIBUTING.md +386 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/ISSUE_TEMPLATE/bug-report.yml +45 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/ISSUE_TEMPLATE/config.yml +8 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/dependabot.yml +16 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/labeler.yml +8 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/labeler_merged.yml +3 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/pull_request_template.md +19 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/workflows/ci.yml +969 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/workflows/configure.yml +84 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/workflows/format.yml +48 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/workflows/labeler.yml +16 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/workflows/pip.yml +103 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.gitignore +45 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.pre-commit-config.yaml +151 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.readthedocs.yml +3 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/CMakeLists.txt +297 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/LICENSE +29 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/MANIFEST.in +6 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/README.rst +180 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/Doxyfile +23 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/Makefile +192 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/_static/theme_overrides.css +11 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/chrono.rst +81 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/custom.rst +93 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/eigen.rst +310 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/functional.rst +109 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/index.rst +43 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/overview.rst +171 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/stl.rst +251 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/strings.rst +305 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/classes.rst +1297 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/embedding.rst +262 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/exceptions.rst +396 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/functions.rst +568 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/misc.rst +337 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/pycpp/index.rst +13 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/pycpp/numpy.rst +463 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/pycpp/object.rst +286 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/pycpp/utilities.rst +155 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/smart_ptrs.rst +174 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/basics.rst +308 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/benchmark.py +91 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/benchmark.rst +95 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/changelog.rst +2050 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/classes.rst +542 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/cmake/index.rst +8 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/compiling.rst +648 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/conf.py +381 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/faq.rst +343 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/index.rst +48 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/installing.rst +105 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/limitations.rst +72 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/pybind11-logo.png +0 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/pybind11_vs_boost_python1.png +0 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/pybind11_vs_boost_python1.svg +427 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/pybind11_vs_boost_python2.png +0 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/pybind11_vs_boost_python2.svg +427 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/reference.rst +130 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/release.rst +96 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/requirements.txt +8 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/upgrade.rst +548 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/attr.h +605 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/buffer_info.h +144 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/cast.h +1432 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/chrono.h +213 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/common.h +2 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/complex.h +65 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/class.h +709 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/common.h +1021 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/descr.h +104 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/init.h +346 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/internals.h +467 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/type_caster_base.h +978 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/typeid.h +55 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/eigen.h +606 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/embed.h +284 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/eval.h +163 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/functional.h +121 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/gil.h +193 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/iostream.h +275 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/numpy.h +1741 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/operators.h +163 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/options.h +65 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/pybind11.h +2497 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/pytypes.h +1879 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/stl/filesystem.h +103 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/stl.h +375 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/stl_bind.h +747 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/noxfile.py +88 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/__init__.py +11 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/__main__.py +52 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/_version.py +12 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/_version.pyi +6 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/commands.py +21 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/py.typed +0 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/setup_helpers.py +482 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/setup_helpers.pyi +63 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pyproject.toml +41 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/setup.cfg +56 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/setup.py +155 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/CMakeLists.txt +503 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/conftest.py +208 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/constructor_stats.h +275 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/cross_module_gil_utils.cpp +73 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/env.py +33 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/extra_python_package/pytest.ini +0 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/extra_python_package/test_files.py +279 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/extra_setuptools/pytest.ini +0 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/extra_setuptools/test_setuphelper.py +143 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/local_bindings.h +85 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/object.h +179 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/pybind11_cross_module_tests.cpp +151 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/pybind11_tests.cpp +91 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/pybind11_tests.h +85 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/pytest.ini +19 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/requirements.txt +12 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_async.cpp +26 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_async.py +25 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_buffers.cpp +216 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_buffers.py +163 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_builtin_casters.cpp +286 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_builtin_casters.py +536 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_call_policies.cpp +107 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_call_policies.py +248 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_callbacks.cpp +227 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_callbacks.py +202 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_chrono.cpp +84 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_chrono.py +210 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_class.cpp +550 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_class.py +473 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/CMakeLists.txt +84 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/embed.cpp +21 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/installed_embed/CMakeLists.txt +28 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/installed_function/CMakeLists.txt +39 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/installed_target/CMakeLists.txt +46 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/main.cpp +6 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/subdirectory_embed/CMakeLists.txt +41 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/subdirectory_function/CMakeLists.txt +35 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/subdirectory_target/CMakeLists.txt +41 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/test.py +10 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_constants_and_functions.cpp +165 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_constants_and_functions.py +53 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_copy_move.cpp +238 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_copy_move.py +126 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_custom_type_casters.cpp +141 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_custom_type_casters.py +117 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_custom_type_setup.cpp +41 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_custom_type_setup.py +50 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_docstring_options.cpp +69 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_docstring_options.py +42 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_eigen.cpp +348 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_eigen.py +771 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_embed/CMakeLists.txt +47 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_embed/catch.cpp +22 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_embed/external_module.cpp +23 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_embed/test_interpreter.cpp +326 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_embed/test_interpreter.py +15 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_enum.cpp +148 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_enum.py +272 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_eval.cpp +119 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_eval.py +51 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_eval_call.py +5 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_exceptions.cpp +285 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_exceptions.h +12 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_exceptions.py +265 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_factory_constructors.cpp +397 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_factory_constructors.py +520 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_gil_scoped.cpp +49 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_gil_scoped.py +94 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_iostream.cpp +125 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_iostream.py +331 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_kwargs_and_defaults.cpp +153 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_kwargs_and_defaults.py +284 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_local_bindings.cpp +107 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_local_bindings.py +257 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_methods_and_attributes.cpp +412 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_methods_and_attributes.py +517 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_modules.cpp +102 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_modules.py +92 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_multiple_inheritance.cpp +233 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_multiple_inheritance.py +360 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_numpy_array.cpp +472 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_numpy_array.py +593 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_numpy_dtypes.cpp +524 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_numpy_dtypes.py +441 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_numpy_vectorize.cpp +103 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_numpy_vectorize.py +267 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_opaque_types.cpp +73 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_opaque_types.py +59 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_operator_overloading.cpp +235 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_operator_overloading.py +146 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_pickling.cpp +189 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_pickling.py +82 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_pytypes.cpp +560 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_pytypes.py +651 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_sequences_and_iterators.cpp +500 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_sequences_and_iterators.py +253 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_smart_ptr.cpp +452 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_smart_ptr.py +318 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_stl.cpp +342 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_stl.py +291 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_stl_binders.cpp +131 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_stl_binders.py +318 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_tagbased_polymorphic.cpp +144 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_tagbased_polymorphic.py +29 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_thread.cpp +66 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_thread.py +44 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_union.cpp +22 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_union.py +9 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_virtual_functions.cpp +510 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_virtual_functions.py +408 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/valgrind-numpy-scipy.supp +140 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/valgrind-python.supp +117 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/FindCatch.cmake +70 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/FindEigen3.cmake +86 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/FindPythonLibsNew.cmake +257 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/check-style.sh +44 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/cmake_uninstall.cmake.in +23 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/libsize.py +39 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/make_changelog.py +64 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/pybind11Common.cmake +402 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/pybind11Config.cmake.in +233 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/pybind11NewTools.cmake +276 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/pybind11Tools.cmake +214 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/pyproject.toml +3 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/setup_global.py.in +65 -0
- xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/setup_main.py.in +41 -0
- xcoll/scattering_routines/geant4/collimasim/pyproject.toml +8 -0
- xcoll/scattering_routines/geant4/collimasim/setup.py +144 -0
- xcoll/scattering_routines/geant4/collimasim/src/collimasim/BDSPyATInterface.cpp +403 -0
- xcoll/scattering_routines/geant4/collimasim/src/collimasim/BDSPyATInterface.hh +100 -0
- xcoll/scattering_routines/geant4/collimasim/src/collimasim/BDSXtrackInterface.cpp +763 -0
- xcoll/scattering_routines/geant4/collimasim/src/collimasim/BDSXtrackInterface.hh +118 -0
- xcoll/scattering_routines/geant4/collimasim/src/collimasim/__init__.py +8 -0
- xcoll/scattering_routines/geant4/collimasim/src/collimasim/bindings.cpp +63 -0
- xcoll/scattering_routines/geant4/collimasim/src/collimasim/pyCollimatorPass.py +142 -0
- xcoll/scattering_routines/geant4/collimasim/src/collimasim/xtrack_collimator.py +556 -0
- xcoll/scattering_routines/geant4/collimasim/src/collimasim.egg-info/PKG-INFO +6 -0
- xcoll/scattering_routines/geant4/collimasim/src/collimasim.egg-info/SOURCES.txt +24 -0
- xcoll/scattering_routines/geant4/collimasim/src/collimasim.egg-info/dependency_links.txt +1 -0
- xcoll/scattering_routines/geant4/collimasim/src/collimasim.egg-info/not-zip-safe +1 -0
- xcoll/scattering_routines/geant4/collimasim/src/collimasim.egg-info/top_level.txt +1 -0
- xcoll/scattering_routines/geant4/collimasim/tests/README.md +25 -0
- xcoll/scattering_routines/geant4/collimasim/tests/resources/CollDB_forions.dat +25 -0
- xcoll/scattering_routines/geant4/collimasim/tests/resources/CollDB_new_example.dat +18 -0
- xcoll/scattering_routines/geant4/collimasim/tests/resources/CollDB_old_example.dat +68 -0
- xcoll/scattering_routines/geant4/collimasim/tests/resources/CollDB_testing.dat +15 -0
- xcoll/scattering_routines/geant4/collimasim/tests/resources/CollDB_yaml_example.yaml +110 -0
- xcoll/scattering_routines/geant4/collimasim/tests/resources/collgaps.dat +7 -0
- xcoll/scattering_routines/geant4/collimasim/tests/resources/collgaps_pyat_test.dat +3 -0
- xcoll/scattering_routines/geant4/collimasim/tests/resources/collonly_twiss_file_example.tfs +54 -0
- xcoll/scattering_routines/geant4/collimasim/tests/resources/settings.gmad +3 -0
- xcoll/scattering_routines/geant4/collimasim/tests/resources/settings_black_absorber.gmad +3 -0
- xcoll/scattering_routines/geant4/collimasim/tests/resources/settings_ions.gmad +5 -0
- xcoll/scattering_routines/geant4/collimasim/tests/resources/twiss_file_testing.tfs +51 -0
- xcoll/scattering_routines/geant4/collimasim/tests/test_pyat.py +65 -0
- xcoll/scattering_routines/geant4/collimasim/tests/test_pyat_passmethod.py +59 -0
- xcoll/scattering_routines/geant4/collimasim/tests/test_pyat_tracking.py +102 -0
- xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack.py +75 -0
- xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_angle.py +74 -0
- xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_colldb_load.py +84 -0
- xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_interaction.py +159 -0
- xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_interaction_ion.py +99 -0
- xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_ions.py +78 -0
- xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_lost_energy.py +88 -0
- xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_tilt.py +80 -0
- xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_tracking.py +97 -0
- xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_tracking_ions.py +96 -0
- xcoll/scattering_routines/geometry/__init__.py +6 -0
- xcoll/scattering_routines/geometry/collimator_geometry.h +218 -0
- xcoll/scattering_routines/geometry/crystal_geometry.h +153 -0
- xcoll/scattering_routines/geometry/geometry.py +26 -0
- xcoll/scattering_routines/geometry/get_s.h +92 -0
- xcoll/scattering_routines/geometry/methods.h +111 -0
- xcoll/scattering_routines/geometry/objects.h +154 -0
- xcoll/scattering_routines/geometry/rotation.h +23 -0
- xcoll/scattering_routines/geometry/segments.h +226 -0
- xcoll/scattering_routines/geometry/sort.h +184 -0
- {xcoll-0.3.6.dist-info → xcoll-0.5.0.dist-info}/METADATA +1 -1
- xcoll-0.5.0.dist-info/RECORD +413 -0
- xcoll/beam_elements/collimators_src/absorber.h +0 -141
- xcoll/beam_elements/collimators_src/everest_collimator.h +0 -142
- xcoll/beam_elements/collimators_src/everest_crystal.h +0 -115
- xcoll/collimator_settings.py +0 -457
- xcoll/impacts/__init__.py +0 -1
- xcoll/impacts/impacts.py +0 -102
- xcoll/impacts/impacts_src/impacts.h +0 -99
- xcoll/scattering_routines/everest/crystal.h +0 -1302
- xcoll/scattering_routines/everest/scatter.h +0 -169
- xcoll/scattering_routines/everest/scatter_crystal.h +0 -260
- xcoll/scattering_routines/fluka/build_fluka_input.py +0 -58
- xcoll-0.3.6.dist-info/RECORD +0 -111
- {xcoll-0.3.6.dist-info → xcoll-0.5.0.dist-info}/LICENSE +0 -0
- {xcoll-0.3.6.dist-info → xcoll-0.5.0.dist-info}/NOTICE +0 -0
- {xcoll-0.3.6.dist-info → xcoll-0.5.0.dist-info}/WHEEL +0 -0
xcoll/manager.py
CHANGED
|
@@ -1,945 +1,10 @@
|
|
|
1
1
|
# copyright ############################### #
|
|
2
2
|
# This file is part of the Xcoll Package. #
|
|
3
|
-
# Copyright (c) CERN,
|
|
3
|
+
# Copyright (c) CERN, 2024. #
|
|
4
4
|
# ######################################### #
|
|
5
5
|
|
|
6
|
-
import json
|
|
7
|
-
from pathlib import Path
|
|
8
|
-
import numpy as np
|
|
9
|
-
import pandas as pd
|
|
10
|
-
|
|
11
|
-
from .beam_elements import BaseCollimator, BlackAbsorber, EverestCollimator, EverestCrystal, _all_collimator_types, element_classes
|
|
12
|
-
from .colldb import CollimatorDatabase
|
|
13
|
-
from .impacts import CollimatorImpacts
|
|
14
|
-
from .scattering_routines.everest.materials import SixTrack_to_xcoll, CrystalMaterial
|
|
15
|
-
|
|
16
|
-
import xobjects as xo
|
|
17
|
-
import xpart as xp
|
|
18
|
-
import xtrack as xt
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
# Logic of buffers:
|
|
22
|
-
# A buffer is a continuous stream of memory, containing a bunch of xobjects.
|
|
23
|
-
# It is an architecture-invariant way to work with pointers, as the pointers to the individual
|
|
24
|
-
# xobjects are stored as offsets to the start of the buffer.
|
|
25
|
-
# The tracker manages three buffers: one for the line and all elements, one for the particles,
|
|
26
|
-
# and an io_buffer for record logging.
|
|
27
6
|
|
|
28
7
|
class CollimatorManager:
|
|
29
8
|
|
|
30
|
-
_init_vars = ['_colldb', 'line', 'beam', 'capacity', 'record_impacts', '_context', '_buffer', 'io_buffer', '_part_buffer']
|
|
31
|
-
_init_var_defaults = {'_colldb': None, 'beam': None, 'capacity': 1e6, 'record_impacts': False, \
|
|
32
|
-
'_context': None, '_buffer': None, 'io_buffer': None, '_part_buffer': None}
|
|
33
|
-
|
|
34
|
-
# -------------------------------
|
|
35
|
-
# ------ Loading functions ------
|
|
36
|
-
# -------------------------------
|
|
37
|
-
|
|
38
|
-
@classmethod
|
|
39
|
-
def from_yaml(cls, file, **kwargs):
|
|
40
|
-
if '_colldb' in kwargs.keys():
|
|
41
|
-
raise ValueError("Cannot load CollimatorDatabase file and specify '_colldb' argument in loader!")
|
|
42
|
-
kwargs_colldb = {key: val for key, val in kwargs.items() if key in CollimatorDatabase._init_vars}
|
|
43
|
-
kwargs_manager = {key: val for key, val in kwargs.items() if key in cls._init_vars}
|
|
44
|
-
colldb = CollimatorDatabase.from_yaml(file, **kwargs_colldb)
|
|
45
|
-
return cls(_colldb=colldb, **kwargs_manager)
|
|
46
|
-
|
|
47
|
-
@classmethod
|
|
48
|
-
def from_json(cls, file, **kwargs):
|
|
49
|
-
if '_colldb' in kwargs.keys():
|
|
50
|
-
raise ValueError("Cannot load CollimatorDatabase file and specify '_colldb' argument in loader!")
|
|
51
|
-
kwargs_colldb = {key: val for key, val in kwargs.items() if key in CollimatorDatabase._init_vars}
|
|
52
|
-
kwargs_manager = {key: val for key, val in kwargs.items() if key in cls._init_vars}
|
|
53
|
-
colldb = CollimatorDatabase.from_json(file, **kwargs_colldb)
|
|
54
|
-
return cls(_colldb=colldb, **kwargs_manager)
|
|
55
|
-
|
|
56
|
-
@classmethod
|
|
57
|
-
def from_dict(cls, file, **kwargs):
|
|
58
|
-
if '_colldb' in kwargs.keys():
|
|
59
|
-
raise ValueError("Cannot load CollimatorDatabase file and specify '_colldb' argument in loader!")
|
|
60
|
-
kwargs_colldb = {key: val for key, val in kwargs.items() if key in CollimatorDatabase._init_vars}
|
|
61
|
-
kwargs_manager = {key: val for key, val in kwargs.items() if key in cls._init_vars}
|
|
62
|
-
colldb = CollimatorDatabase.from_dict(file, **kwargs_colldb)
|
|
63
|
-
return cls(_colldb=colldb, **kwargs_manager)
|
|
64
|
-
|
|
65
|
-
@classmethod
|
|
66
|
-
def from_SixTrack(cls, file, **kwargs):
|
|
67
|
-
if '_colldb' in kwargs.keys():
|
|
68
|
-
raise ValueError("Cannot load CollimatorDatabase file and specify '_colldb' argument in loader!")
|
|
69
|
-
kwargs_colldb = {key: val for key, val in kwargs.items() if key in CollimatorDatabase._init_vars}
|
|
70
|
-
kwargs_manager = {key: val for key, val in kwargs.items() if key in cls._init_vars}
|
|
71
|
-
colldb = CollimatorDatabase.from_SixTrack(file, **kwargs_colldb)
|
|
72
|
-
return cls(_colldb=colldb, **kwargs_manager)
|
|
73
|
-
|
|
74
|
-
|
|
75
9
|
def __init__(self, **kwargs):
|
|
76
|
-
|
|
77
|
-
for var in self._init_vars:
|
|
78
|
-
if var in self._init_var_defaults:
|
|
79
|
-
kwargs.setdefault(var, self._init_var_defaults[var])
|
|
80
|
-
elif var not in kwargs.keys():
|
|
81
|
-
raise ValueError(f"CollimatorManager is missing required argument '{var}'!")
|
|
82
|
-
|
|
83
|
-
colldb = kwargs['_colldb']
|
|
84
|
-
if not isinstance(colldb, CollimatorDatabase):
|
|
85
|
-
# TODO allow None as empty database
|
|
86
|
-
raise ValueError("The variable '_colldb' needs to be an xcoll CollimatorDatabase object!")
|
|
87
|
-
else:
|
|
88
|
-
self.colldb = colldb
|
|
89
|
-
|
|
90
|
-
line = kwargs['line']
|
|
91
|
-
beam = kwargs['beam']
|
|
92
|
-
if isinstance(beam, str):
|
|
93
|
-
beam = int(beam[-1])
|
|
94
|
-
if not isinstance(line, xt.Line):
|
|
95
|
-
raise ValueError("The variable 'line' needs to be an xtrack Line object!")
|
|
96
|
-
else:
|
|
97
|
-
self.line = line
|
|
98
|
-
self.line._needs_rng = True # TODO not needed if only BlackAbsorbers
|
|
99
|
-
if beam is not None and beam > 1:
|
|
100
|
-
self._line_is_reversed = True
|
|
101
|
-
else:
|
|
102
|
-
self._line_is_reversed = False
|
|
103
|
-
self._machine_length = self.line.get_length()
|
|
104
|
-
|
|
105
|
-
# Create _buffer, _context, and _io_buffer
|
|
106
|
-
_buffer = kwargs['_buffer']
|
|
107
|
-
_context = kwargs['_context']
|
|
108
|
-
if _buffer is None:
|
|
109
|
-
if _context is None:
|
|
110
|
-
_context = xo.ContextCpu()
|
|
111
|
-
_buffer = _context.new_buffer()
|
|
112
|
-
elif _context is not None and _buffer.context != _context:
|
|
113
|
-
raise ValueError("The provided buffer and context do not match! "
|
|
114
|
-
+ "Make sure the buffer is generated inside the provided context, or alternatively, "
|
|
115
|
-
+ "only pass one of _buffer or _context.")
|
|
116
|
-
self._buffer = _buffer
|
|
117
|
-
self._part_buffer = kwargs['_part_buffer']
|
|
118
|
-
if self._part_buffer is not None and self._part_buffer.context != _context:
|
|
119
|
-
raise ValueError("The provided particle buffer and context do not match! "
|
|
120
|
-
+ "Make sure the particle buffer is generated inside the provided context.")
|
|
121
|
-
|
|
122
|
-
# TODO: currently capacity is only for io_buffer (hence for impacts).
|
|
123
|
-
# Do we need it in the _buffer as well?
|
|
124
|
-
self._capacity = int(kwargs['capacity'])
|
|
125
|
-
io_buffer = kwargs['io_buffer']
|
|
126
|
-
if io_buffer is None:
|
|
127
|
-
io_buffer = xt.new_io_buffer(_context=self._buffer.context, capacity=self.capacity)
|
|
128
|
-
elif self._buffer.context != io_buffer._context:
|
|
129
|
-
raise ValueError("The provided io_buffer lives on a different context than the buffer!")
|
|
130
|
-
self._io_buffer = io_buffer
|
|
131
|
-
|
|
132
|
-
# Initialise impacts table
|
|
133
|
-
self._recording_elements = []
|
|
134
|
-
self.record_impacts = kwargs['record_impacts']
|
|
135
|
-
self._impacts = None
|
|
136
|
-
|
|
137
|
-
# Variables for lossmap
|
|
138
|
-
self._lossmap = None
|
|
139
|
-
self._summary = None
|
|
140
|
-
self._part = None
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
def __getitem__(self, name):
|
|
144
|
-
return self.colldb[name]
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
@property
|
|
148
|
-
def machine_length(self):
|
|
149
|
-
return self._machine_length
|
|
150
|
-
|
|
151
|
-
@property
|
|
152
|
-
def impacts(self):
|
|
153
|
-
return self._impacts
|
|
154
|
-
|
|
155
|
-
@property
|
|
156
|
-
def record_impacts(self):
|
|
157
|
-
return self._record_impacts
|
|
158
|
-
|
|
159
|
-
@record_impacts.setter
|
|
160
|
-
def record_impacts(self, record_impacts):
|
|
161
|
-
if record_impacts is False or record_impacts is None:
|
|
162
|
-
record_stop = [self.line[name] for name in self._recording_elements]
|
|
163
|
-
record_start = False
|
|
164
|
-
elif record_impacts is True:
|
|
165
|
-
record_stop = []
|
|
166
|
-
record_start = True
|
|
167
|
-
else:
|
|
168
|
-
if not hasattr(record_impacts, '__iter__') or isinstance(record_impacts, str):
|
|
169
|
-
record_impacts = [record_impacts]
|
|
170
|
-
record_stop = [self.line[name] for name in set(self._recording_elements) - set(record_impacts)]
|
|
171
|
-
record_start = record_impacts
|
|
172
|
-
|
|
173
|
-
# We stop logging these elements
|
|
174
|
-
if record_stop:
|
|
175
|
-
if self.line.tracker is not None:
|
|
176
|
-
self.line.tracker._check_invalidated()
|
|
177
|
-
xt.stop_internal_logging(elements=record_stop)
|
|
178
|
-
# Removed the stopped collimators from list of logged elements
|
|
179
|
-
self._recording_elements = list(set(self._recording_elements) - set(record_stop))
|
|
180
|
-
|
|
181
|
-
# We will start logging these elements
|
|
182
|
-
self._record_impacts = record_start
|
|
183
|
-
self._set_record_impacts()
|
|
184
|
-
|
|
185
|
-
def _set_record_impacts(self):
|
|
186
|
-
record_impacts = self._record_impacts
|
|
187
|
-
if record_impacts is True:
|
|
188
|
-
record_impacts = self.collimator_names
|
|
189
|
-
if record_impacts is False or record_impacts is None:
|
|
190
|
-
record_impacts = []
|
|
191
|
-
if not hasattr(record_impacts, '__iter__') or isinstance(record_impacts, str):
|
|
192
|
-
record_impacts = [record_impacts]
|
|
193
|
-
if record_impacts and np.all([isinstance(self.line[elem], BaseCollimator) for elem in record_impacts]):
|
|
194
|
-
for name in record_impacts:
|
|
195
|
-
if name not in self.line.element_names:
|
|
196
|
-
raise ValueError(f"Trying to initialise impact table, but collimator {name} not found in line!")
|
|
197
|
-
elements_to_record = list(set(record_impacts) - set(self._recording_elements))
|
|
198
|
-
elements_to_stop = list(set(self._recording_elements) - set(record_impacts))
|
|
199
|
-
if elements_to_stop:
|
|
200
|
-
# These should have been stopped by the setter function above
|
|
201
|
-
raise ValueError("Some elements are recording but are not supposed to!")
|
|
202
|
-
# Any new elements that need recording but aren't recording yet?
|
|
203
|
-
if elements_to_record:
|
|
204
|
-
elements_to_record = [self.line[name] for name in elements_to_record]
|
|
205
|
-
if self.impacts is None:
|
|
206
|
-
self._impacts = xt.start_internal_logging(io_buffer=self._io_buffer, capacity=self.capacity, \
|
|
207
|
-
elements=elements_to_record)
|
|
208
|
-
else:
|
|
209
|
-
xt.start_internal_logging(io_buffer=self._io_buffer, capacity=self.capacity, \
|
|
210
|
-
record=self.impacts, elements=elements_to_record)
|
|
211
|
-
self._recording_elements = record_impacts
|
|
212
|
-
self.impacts._coll_ids = {self.line.element_names.index(name): name for name in self._recording_elements}
|
|
213
|
-
|
|
214
|
-
@property
|
|
215
|
-
def capacity(self):
|
|
216
|
-
return self._capacity
|
|
217
|
-
|
|
218
|
-
@capacity.setter
|
|
219
|
-
def capacity(self, capacity):
|
|
220
|
-
capacity = int(capacity)
|
|
221
|
-
if capacity < self.capacity:
|
|
222
|
-
raise NotImplementedError("Shrinking of capacity not yet implemented!")
|
|
223
|
-
elif capacity == self.capacity:
|
|
224
|
-
return
|
|
225
|
-
else:
|
|
226
|
-
self._io_buffer.grow(capacity-self.capacity)
|
|
227
|
-
if self.impacts is not None:
|
|
228
|
-
# TODO: increase capacity of iobuffer AND of _impacts
|
|
229
|
-
raise NotImplementedError
|
|
230
|
-
|
|
231
|
-
@property
|
|
232
|
-
def collimator_names(self):
|
|
233
|
-
# TODO: should only sort whenever collimators are added to colldb
|
|
234
|
-
# or when positions are updated
|
|
235
|
-
db = self.colldb._colldb
|
|
236
|
-
# names = list(db[db.active==True].index)
|
|
237
|
-
names = list(db.index)
|
|
238
|
-
if not np.any([s is None for s in db.s_center]):
|
|
239
|
-
names.sort(key=lambda nn: db.loc[nn, 's_center'])
|
|
240
|
-
return names
|
|
241
|
-
|
|
242
|
-
@property
|
|
243
|
-
def s_front(self):
|
|
244
|
-
return self.colldb.s_center - self.colldb.active_length/2 - self.colldb.inactive_front
|
|
245
|
-
|
|
246
|
-
@property
|
|
247
|
-
def s_active_front(self):
|
|
248
|
-
return self.colldb.s_center - self.colldb.active_length/2
|
|
249
|
-
|
|
250
|
-
@property
|
|
251
|
-
def s_center(self):
|
|
252
|
-
return self.colldb.s_center
|
|
253
|
-
|
|
254
|
-
@property
|
|
255
|
-
def s_active_back(self):
|
|
256
|
-
return self.colldb.s_center + self.colldb.active_length/2
|
|
257
|
-
|
|
258
|
-
@property
|
|
259
|
-
def s_back(self):
|
|
260
|
-
return self.colldb.s_center + self.colldb.active_length/2 + self.colldb.inactive_back
|
|
261
|
-
|
|
262
|
-
def install_black_absorbers(self, names=None, *, verbose=False):
|
|
263
|
-
if names is None:
|
|
264
|
-
names = self.collimator_names
|
|
265
|
-
def install_func(thiscoll, name):
|
|
266
|
-
return BlackAbsorber(
|
|
267
|
-
inactive_front=thiscoll['inactive_front'],
|
|
268
|
-
inactive_back=thiscoll['inactive_back'],
|
|
269
|
-
active_length=thiscoll['active_length'],
|
|
270
|
-
angle=[thiscoll['angle_L'],thiscoll['angle_R']],
|
|
271
|
-
active=False,
|
|
272
|
-
_tracking=False,
|
|
273
|
-
_buffer=self._buffer
|
|
274
|
-
)
|
|
275
|
-
self._install_collimators(names, install_func=install_func, verbose=verbose)
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
def install_everest_collimators(self, names=None, *, verbose=False):
|
|
279
|
-
if names is None:
|
|
280
|
-
names = self.collimator_names
|
|
281
|
-
names = list(names) # Dataframe does not like to be indexed with a set
|
|
282
|
-
df = self.colldb._colldb.loc[names]
|
|
283
|
-
df_coll = df[[c is None for c in df.crystal]]
|
|
284
|
-
df_cry = df[[c is not None for c in df.crystal]]
|
|
285
|
-
# Do the installations (start with crystals to avoid recompilation)
|
|
286
|
-
if len(df_cry) > 0:
|
|
287
|
-
def install_func(thiscoll, name):
|
|
288
|
-
material = SixTrack_to_xcoll[thiscoll['material']]
|
|
289
|
-
if len(material) < 2:
|
|
290
|
-
raise ValueError(f"Could not find crystal material definition from variable {thiscoll['material']}!")
|
|
291
|
-
material = material[1]
|
|
292
|
-
if not isinstance(material, CrystalMaterial):
|
|
293
|
-
raise ValueError(f"The material {material.name} is not a Crystalmaterial!")
|
|
294
|
-
return EverestCrystal(
|
|
295
|
-
inactive_front=thiscoll['inactive_front'],
|
|
296
|
-
inactive_back=thiscoll['inactive_back'],
|
|
297
|
-
active_length=thiscoll['active_length'],
|
|
298
|
-
angle=[thiscoll['angle_L'],thiscoll['angle_R']],
|
|
299
|
-
material=material,
|
|
300
|
-
active=False,
|
|
301
|
-
_tracking=False,
|
|
302
|
-
_buffer=self._buffer
|
|
303
|
-
)
|
|
304
|
-
self._install_collimators(df_cry.index.values, install_func=install_func, verbose=verbose)
|
|
305
|
-
if len(df_coll) > 0:
|
|
306
|
-
def install_func(thiscoll, name):
|
|
307
|
-
return EverestCollimator(
|
|
308
|
-
inactive_front=thiscoll['inactive_front'],
|
|
309
|
-
inactive_back=thiscoll['inactive_back'],
|
|
310
|
-
active_length=thiscoll['active_length'],
|
|
311
|
-
angle=[thiscoll['angle_L'],thiscoll['angle_R']],
|
|
312
|
-
material=SixTrack_to_xcoll[thiscoll['material']][0],
|
|
313
|
-
active=False,
|
|
314
|
-
_tracking=False,
|
|
315
|
-
_buffer=self._buffer
|
|
316
|
-
)
|
|
317
|
-
self._install_collimators(df_coll.index.values, install_func=install_func, verbose=verbose)
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
def _install_collimators(self, names, *, install_func, verbose, support_legacy_elements=False):
|
|
321
|
-
# Check that collimator marker exists in Line and CollimatorDatabase,
|
|
322
|
-
# and that tracker is not yet built
|
|
323
|
-
# TODO: need check that all collimators have aperture before and after
|
|
324
|
-
line = self.line
|
|
325
|
-
if not hasattr(names, '__iter__') or isinstance(names, str):
|
|
326
|
-
names = [names]
|
|
327
|
-
df = self.colldb._colldb
|
|
328
|
-
mask = df.index.isin(names)
|
|
329
|
-
for name in names:
|
|
330
|
-
if name not in line.element_names:
|
|
331
|
-
raise Exception(f"Collimator {name} not found in line!")
|
|
332
|
-
elif name not in self.collimator_names:
|
|
333
|
-
raise Exception(f"Warning: Collimator {name} not found in CollimatorDatabase!...")
|
|
334
|
-
if self.tracker_ready:
|
|
335
|
-
raise Exception("Tracker already built!\nPlease install collimators before building "
|
|
336
|
-
+ "tracker!")
|
|
337
|
-
|
|
338
|
-
# Loop over collimators to install
|
|
339
|
-
for name in names:
|
|
340
|
-
|
|
341
|
-
# Get s positions
|
|
342
|
-
# This cannot go outside the loop as the indices will change!
|
|
343
|
-
ss = line.get_s_position()
|
|
344
|
-
|
|
345
|
-
# Get the settings from the CollimatorDatabase
|
|
346
|
-
thiscoll = df.loc[name]
|
|
347
|
-
idx = line.element_names.index(name)
|
|
348
|
-
# Create the collimator element
|
|
349
|
-
newcoll = install_func(thiscoll, name)
|
|
350
|
-
collimator_class = newcoll.__class__
|
|
351
|
-
|
|
352
|
-
# Check that collimator is not installed as different type
|
|
353
|
-
# TODO: automatically replace collimator type and print warning
|
|
354
|
-
if isinstance(line[name], tuple(_all_collimator_types - {collimator_class})):
|
|
355
|
-
raise ValueError(f"Trying to install {name} as {collimator_class.__name__},"
|
|
356
|
-
+ f" but it is already installed as {type(line[name]).__name__}!\n"
|
|
357
|
-
+ f"Please reconstruct the line.")
|
|
358
|
-
|
|
359
|
-
# Check that collimator is not installed previously
|
|
360
|
-
elif isinstance(line[name], collimator_class):
|
|
361
|
-
if df.loc[name,'collimator_type'] != collimator_class.__name__:
|
|
362
|
-
raise Exception(f"Something is wrong: Collimator {name} already installed in "
|
|
363
|
-
+ f"line as {collimator_class.__name__} element, but registered "
|
|
364
|
-
+ f"in CollimatorDatabase as {df.loc[name, 'collimator_type']}. "
|
|
365
|
-
+ f"Please reconstruct the line.")
|
|
366
|
-
if verbose: print(f"Collimator {name} already installed. Skipping...")
|
|
367
|
-
continue
|
|
368
|
-
|
|
369
|
-
# TODO: only allow Marker elements, no Drifts!!
|
|
370
|
-
# How to do this with importing a line for MAD-X or SixTrack...?
|
|
371
|
-
elif not isinstance(line[name], (xt.Marker, xt.Drift)) and not support_legacy_elements:
|
|
372
|
-
raise ValueError(f"Trying to install {name} as {collimator_class.__name__},"
|
|
373
|
-
+ f" but the line element to replace is not an xtrack.Marker "
|
|
374
|
-
+ f"(or xtrack.Drift)!\nPlease check the name, or correct the "
|
|
375
|
-
+ f"element.")
|
|
376
|
-
|
|
377
|
-
if verbose: print(f"Installing {name:20} as {collimator_class.__name__}")
|
|
378
|
-
# Update the position and type in the CollimatorDatabase
|
|
379
|
-
df.loc[name,'s_center'] = ss[idx]
|
|
380
|
-
df.loc[name,'collimator_type'] = collimator_class.__name__
|
|
381
|
-
|
|
382
|
-
# Find apertures and store them
|
|
383
|
-
# TODO: same with cryotanks for FLUKA
|
|
384
|
-
# TODO: use compound info -> need full collimator info from MADX
|
|
385
|
-
# TODO: this is all very hacky....
|
|
386
|
-
aper_before = {}
|
|
387
|
-
aper_after = {}
|
|
388
|
-
if f'{name}_mken' in line.element_names\
|
|
389
|
-
and f'{name}_mkex'in line.element_names:
|
|
390
|
-
# TODO what with transformations? How to shift them in s if different?
|
|
391
|
-
aper_before = {nn.replace('mken', 'upstream'): line[nn].copy()
|
|
392
|
-
for nn in line.element_names if nn.startswith(f'{name}_mken_aper')}
|
|
393
|
-
aper_after = {nn.replace('mkex', 'downstream'): line[nn].copy()
|
|
394
|
-
for nn in line.element_names if nn.startswith(f'{name}_mkex_aper')}
|
|
395
|
-
if len(aper_before) == 0:
|
|
396
|
-
# TODO what with transformations? How to shift them in s from centre to start/end?
|
|
397
|
-
aper_before = {nn.replace('_aper', '_upstream_aper'): line[nn].copy()
|
|
398
|
-
for nn in line.element_names if nn.startswith(f'{name}_aper')}
|
|
399
|
-
if len(aper_after) == 0:
|
|
400
|
-
aper_after = {nn.replace('_aper', '_downstream_aper'): line[nn].copy()
|
|
401
|
-
for nn in line.element_names if nn.startswith(f'{name}_aper')}
|
|
402
|
-
if len(aper_before) == 0 or len(aper_after) == 0:
|
|
403
|
-
print(f"Warning: No aperture found for collimator {name}!")
|
|
404
|
-
|
|
405
|
-
# Remove stuff at location of collimator
|
|
406
|
-
l = thiscoll['active_length']
|
|
407
|
-
to_remove = []
|
|
408
|
-
i = idx - 1
|
|
409
|
-
# We remove everything between the beginning and end of the collimator except drifts
|
|
410
|
-
while ss[i] >= ss[idx] - l/2:
|
|
411
|
-
el = line[i]
|
|
412
|
-
nn = line.element_names[i]
|
|
413
|
-
if el.__class__.__name__ == 'Drift':
|
|
414
|
-
i -= 1
|
|
415
|
-
continue
|
|
416
|
-
if hasattr(el, 'length') and el.length > 0:
|
|
417
|
-
raise ValueError(f"Found active element {nn} with length "
|
|
418
|
-
+ f"{el.length} at location inside collimator!")
|
|
419
|
-
# I don't like this class selection...
|
|
420
|
-
if not el.__class__.__name__ in ['Marker', 'SRotation', \
|
|
421
|
-
'YRotation', 'XRotation', 'XYShift'] \
|
|
422
|
-
and not el.__class__.__name__.startswith('Limit'):
|
|
423
|
-
print(f"Warning: Removed active element {nn} "
|
|
424
|
-
+ f"at location inside collimator!")
|
|
425
|
-
to_remove.append(nn)
|
|
426
|
-
i -= 1
|
|
427
|
-
i = idx + 1
|
|
428
|
-
while ss[i] <= ss[idx] + l/2:
|
|
429
|
-
el = line[i]
|
|
430
|
-
nn = line.element_names[i]
|
|
431
|
-
if el.__class__.__name__ == 'Drift':
|
|
432
|
-
i += 1
|
|
433
|
-
continue
|
|
434
|
-
if hasattr(el, 'length') and el.length > 0:
|
|
435
|
-
raise ValueError(f"Found active element {nn} with length "
|
|
436
|
-
+ f"{el.length} at location inside collimator!")
|
|
437
|
-
# I don't like this class selection...
|
|
438
|
-
if not el.__class__.__name__ in ['Marker', 'SRotation', \
|
|
439
|
-
'YRotation', 'XRotation', 'XYShift'] \
|
|
440
|
-
and not el.__class__.__name__.startswith('Limit'):
|
|
441
|
-
print(f"Warning: Removed active element {line.element_names[i]} "
|
|
442
|
-
+ f"at location inside collimator!")
|
|
443
|
-
to_remove.append(nn)
|
|
444
|
-
i += 1
|
|
445
|
-
for nn in to_remove:
|
|
446
|
-
# TODO: need to update Compounds
|
|
447
|
-
line.element_names.remove(nn)
|
|
448
|
-
line.element_dict.pop(nn)
|
|
449
|
-
|
|
450
|
-
# Do the installation
|
|
451
|
-
s_install = df.loc[name,'s_center'] - thiscoll['active_length']/2 \
|
|
452
|
-
- thiscoll['inactive_front']
|
|
453
|
-
line.insert_element(element=newcoll, name=name, at_s=s_install)
|
|
454
|
-
|
|
455
|
-
# Reinstall apertures
|
|
456
|
-
for aper, el in aper_before.items():
|
|
457
|
-
# TODO: need to update Compounds
|
|
458
|
-
line.insert_element(element=el, name=aper, index=name)
|
|
459
|
-
for aper, el in reversed(aper_after.items()):
|
|
460
|
-
# Reversed because of index+1
|
|
461
|
-
# TODO: need to update Compounds
|
|
462
|
-
line.insert_element(element=el, name=aper,
|
|
463
|
-
index=line.element_names.index(name)+1)
|
|
464
|
-
|
|
465
|
-
self._set_record_impacts()
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
@property
|
|
469
|
-
def installed(self):
|
|
470
|
-
return not any([coll is None for coll in self.colldb.collimator_type])
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
def align_collimators_to(self, align):
|
|
474
|
-
if not self.installed:
|
|
475
|
-
raise ValueError("Some collimators have not yet been installed.\n"
|
|
476
|
-
+ "Please install all collimators before aligning the collimators.")
|
|
477
|
-
self.colldb.align_to = align
|
|
478
|
-
|
|
479
|
-
@property
|
|
480
|
-
def aligned(self):
|
|
481
|
-
return not np.any(
|
|
482
|
-
[x is None for x in self.colldb._colldb.s_align_front]
|
|
483
|
-
+ [ x is None for x in self.colldb._colldb.s_align_back]
|
|
484
|
-
)
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
def build_tracker(self, **kwargs):
|
|
488
|
-
kwargs.setdefault('_buffer', self._buffer)
|
|
489
|
-
kwargs.setdefault('io_buffer', self._io_buffer)
|
|
490
|
-
if kwargs['_buffer'] != self._buffer:
|
|
491
|
-
raise ValueError("Cannot build tracker with different buffer than the CollimatorManager buffer!")
|
|
492
|
-
if kwargs['io_buffer'] != self._io_buffer:
|
|
493
|
-
raise ValueError("Cannot build tracker with different io_buffer than the CollimatorManager io_buffer!")
|
|
494
|
-
if '_context' in kwargs and kwargs['_context'] != self._buffer.context:
|
|
495
|
-
raise ValueError("Cannot build tracker with different context than the CollimatorManager context!")
|
|
496
|
-
self.line.build_tracker(**kwargs)
|
|
497
|
-
self._set_record_impacts()
|
|
498
|
-
|
|
499
|
-
@property
|
|
500
|
-
def tracker_ready(self):
|
|
501
|
-
return self.line is not None and self.line.tracker is not None
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
def _compute_optics(self, recompute=False):
|
|
505
|
-
if not self.tracker_ready:
|
|
506
|
-
raise Exception("Please build tracker before computing the optics for the openings!")
|
|
507
|
-
line = self.line
|
|
508
|
-
|
|
509
|
-
if recompute or not self.colldb._optics_is_ready:
|
|
510
|
-
# TODO: does this fail on Everest? Can the twiss be calculated at the center of the collimator for everest?
|
|
511
|
-
# pos = { *self.s_active_front, *self.s_center, *self.s_active_back }
|
|
512
|
-
pos = list({ *self.s_active_front, *self.s_active_back })
|
|
513
|
-
tw = line.twiss(at_s=pos)
|
|
514
|
-
# tw = tracker.twiss()
|
|
515
|
-
self.colldb._optics = pd.concat([
|
|
516
|
-
self.colldb._optics,
|
|
517
|
-
pd.DataFrame({
|
|
518
|
-
opt: tw[opt] for opt in self.colldb._optics.columns
|
|
519
|
-
# opt: [ np.array(tw[opt])[abs(tw['s']-thispos) < 1e-12][0] for thispos in pos ]
|
|
520
|
-
# for opt in self.colldb._optics.columns
|
|
521
|
-
}, index=pos)
|
|
522
|
-
])
|
|
523
|
-
self.colldb.gamma_rel = line.particle_ref._xobject.gamma0[0]
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
# The variable 'gaps' is meant to specify temporary settings that will overrule the CollimatorDatabase.
|
|
527
|
-
# As such, its settings will be applied to the collimator elements in the line, but not
|
|
528
|
-
# written to the CollimatorDatabase. Hence two successive calls to set_openings will not be combined,
|
|
529
|
-
# and only the last call will be applied to the line.
|
|
530
|
-
# The variable 'to_parking' will send all collimators that are not listed in 'gaps' to parking.
|
|
531
|
-
# Similarily, the variable 'full_open' will set all openings of the collimators that are not
|
|
532
|
-
# listed in 'gaps' to 1m.
|
|
533
|
-
def set_openings(self, gaps={}, *, recompute_optics=False, to_parking=False, full_open=False, support_legacy_elements=False):
|
|
534
|
-
if not self.tracker_ready:
|
|
535
|
-
raise Exception("Please build tracker before setting the openings!")
|
|
536
|
-
colldb = self.colldb
|
|
537
|
-
if not self.installed:
|
|
538
|
-
raise ValueError("Some collimators have not yet been installed.\n"
|
|
539
|
-
+ "Please install all collimators before setting the openings.")
|
|
540
|
-
if to_parking and full_open:
|
|
541
|
-
raise ValueError("Cannot send collimators to parking and open them fully at the same time!")
|
|
542
|
-
if not self.aligned:
|
|
543
|
-
self.align_collimators_to('front')
|
|
544
|
-
|
|
545
|
-
gaps_OLD = colldb.gap
|
|
546
|
-
names = self.collimator_names
|
|
547
|
-
# Override gap if sending to parking
|
|
548
|
-
if to_parking:
|
|
549
|
-
gaps = { **{ name: None for name in names }, **gaps }
|
|
550
|
-
colldb.gap = gaps
|
|
551
|
-
|
|
552
|
-
# Get the optics (to compute the opening)
|
|
553
|
-
self._compute_optics(recompute=recompute_optics)
|
|
554
|
-
if not self.colldb._optics_is_ready:
|
|
555
|
-
raise Exception("Something is wrong: not all optics needed for the jaw openings are calculated!")
|
|
556
|
-
|
|
557
|
-
# Configure collimators
|
|
558
|
-
line = self.line
|
|
559
|
-
for name in names:
|
|
560
|
-
# Override openings if opening fully
|
|
561
|
-
if full_open and name not in gaps.keys():
|
|
562
|
-
line[name].active = False
|
|
563
|
-
# Apply settings to element
|
|
564
|
-
elif isinstance(line[name], BaseCollimator):
|
|
565
|
-
line[name].ref_x = colldb.x[name]
|
|
566
|
-
line[name].ref_y = colldb.y[name]
|
|
567
|
-
line[name].angle = colldb.angle[name]
|
|
568
|
-
line[name].jaw_L = colldb._colldb.jaw_LU[name]
|
|
569
|
-
line[name].jaw_R = colldb._colldb.jaw_RU[name]
|
|
570
|
-
# TODO
|
|
571
|
-
line[name].side = colldb.side[name]
|
|
572
|
-
line[name].active = colldb.active[name]
|
|
573
|
-
if isinstance(line[name], (EverestCollimator, EverestCrystal)) or support_legacy_elements:
|
|
574
|
-
if colldb._colldb.crystal[name] is None:
|
|
575
|
-
line[name].material = SixTrack_to_xcoll[colldb.material[name]][0]
|
|
576
|
-
else:
|
|
577
|
-
line[name].material = SixTrack_to_xcoll[colldb.material[name]][1]
|
|
578
|
-
if isinstance(line[name], EverestCrystal):
|
|
579
|
-
line[name].align_angle = colldb._colldb.align_angle[name]
|
|
580
|
-
line[name].bending_radius = colldb._colldb.bending_radius[name]
|
|
581
|
-
line[name].xdim = colldb._colldb.xdim[name]
|
|
582
|
-
line[name].ydim = colldb._colldb.ydim[name]
|
|
583
|
-
line[name].thick = colldb._colldb.thick[name]
|
|
584
|
-
line[name].miscut = colldb._colldb.miscut[name]
|
|
585
|
-
line[name].lattice = colldb._colldb.crystal[name]
|
|
586
|
-
else:
|
|
587
|
-
raise ValueError(f"Missing implementation for element type of collimator {name}!")
|
|
588
|
-
colldb.gap = gaps_OLD
|
|
589
|
-
|
|
590
|
-
@property
|
|
591
|
-
def openings_set(self):
|
|
592
|
-
# TODO: need to delete jaw positions if some parameters (that would influence it) are changed
|
|
593
|
-
return not np.any(
|
|
594
|
-
[x is None for x in self.colldb._colldb.jaw_LU]
|
|
595
|
-
+ [ x is None for x in self.colldb._colldb.jaw_RU]
|
|
596
|
-
+ [ x is None for x in self.colldb._colldb.jaw_LD]
|
|
597
|
-
+ [ x is None for x in self.colldb._colldb.jaw_RD]
|
|
598
|
-
)
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
def _generate_4D_pencil_one_jaw(self, num_particles, collimator, plane, side, impact_parameter,
|
|
602
|
-
dr_sigmas, transverse_spread_sigma, match_at_s):
|
|
603
|
-
|
|
604
|
-
line = self.line
|
|
605
|
-
|
|
606
|
-
if plane == 'x':
|
|
607
|
-
co_pencil = line[collimator].ref_x
|
|
608
|
-
co_transverse = line[collimator].ref_y
|
|
609
|
-
else:
|
|
610
|
-
co_pencil = line[collimator].ref_y
|
|
611
|
-
co_transverse = line[collimator].ref_x
|
|
612
|
-
|
|
613
|
-
nemitt_x = self.colldb.emittance[0]
|
|
614
|
-
nemitt_y = self.colldb.emittance[1]
|
|
615
|
-
|
|
616
|
-
if side == '+':
|
|
617
|
-
absolute_cut = line[collimator].jaw_LU + co_pencil + impact_parameter
|
|
618
|
-
elif side == '-':
|
|
619
|
-
absolute_cut = line[collimator].jaw_RU + co_pencil - impact_parameter
|
|
620
|
-
|
|
621
|
-
# Collimator plane: generate pencil distribution
|
|
622
|
-
pencil, p_pencil = xp.generate_2D_pencil_with_absolute_cut(num_particles,
|
|
623
|
-
plane=plane, absolute_cut=absolute_cut, dr_sigmas=dr_sigmas,
|
|
624
|
-
side=side, line=line, nemitt_x=nemitt_x, nemitt_y=nemitt_y,
|
|
625
|
-
at_element=collimator, match_at_s=match_at_s
|
|
626
|
-
)
|
|
627
|
-
|
|
628
|
-
# Other plane: generate gaussian distribution in normalized coordinates
|
|
629
|
-
transverse_norm = np.random.normal(loc=co_transverse, scale=transverse_spread_sigma, size=num_particles)
|
|
630
|
-
p_transverse_norm = np.random.normal(scale=transverse_spread_sigma, size=num_particles)
|
|
631
|
-
|
|
632
|
-
return [pencil, p_pencil, transverse_norm, p_transverse_norm]
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
def generate_pencil_on_collimator(self, collimator, num_particles, *, side='+-', impact_parameter=0,
|
|
636
|
-
pencil_spread=1e-6, transverse_impact_parameter=0.,
|
|
637
|
-
transverse_spread_sigma=0.01, longitudinal=None,
|
|
638
|
-
longitudinal_betatron_cut=None, sigma_z=7.61e-2):
|
|
639
|
-
if not self.openings_set:
|
|
640
|
-
raise ValueError("Need to set collimator openings before generating pencil distribution!")
|
|
641
|
-
if not self.tracker_ready:
|
|
642
|
-
raise Exception("Please build tracker before generating pencil distribution!")
|
|
643
|
-
if transverse_impact_parameter != 0.:
|
|
644
|
-
raise NotImplementedError
|
|
645
|
-
|
|
646
|
-
# TODO: check collimator in colldb and installed!
|
|
647
|
-
|
|
648
|
-
if self.colldb.side[collimator] == 'left':
|
|
649
|
-
side = '+'
|
|
650
|
-
if self.colldb.side[collimator] == 'right':
|
|
651
|
-
side = '-'
|
|
652
|
-
|
|
653
|
-
# Define the plane
|
|
654
|
-
angle = self.colldb.angle[collimator]
|
|
655
|
-
if abs(np.mod(angle-90,180)-90) < 1e-6:
|
|
656
|
-
plane = 'x'
|
|
657
|
-
elif abs(np.mod(angle,180)-90) < 1e-6:
|
|
658
|
-
plane = 'y'
|
|
659
|
-
else:
|
|
660
|
-
raise NotImplementedError("Pencil beam on a skew collimator not yet supported!")
|
|
661
|
-
|
|
662
|
-
nemitt_x = self.colldb.emittance[0]
|
|
663
|
-
nemitt_y = self.colldb.emittance[1]
|
|
664
|
-
|
|
665
|
-
# Is it converging or diverging?
|
|
666
|
-
is_converging = self.colldb._optics.loc[self.s_active_front[collimator], 'alf' + plane ] > 0
|
|
667
|
-
print(f"Collimator {collimator} is {'con' if is_converging else 'di'}verging.")
|
|
668
|
-
if is_converging:
|
|
669
|
-
# pencil at front of jaw
|
|
670
|
-
match_at_s = self.s_active_front[collimator]
|
|
671
|
-
sigma = self.colldb._beam_size_front[collimator]
|
|
672
|
-
else:
|
|
673
|
-
# pencil at back of jaw
|
|
674
|
-
match_at_s = self.s_active_back[collimator]
|
|
675
|
-
sigma = self.colldb._beam_size_back[collimator]
|
|
676
|
-
|
|
677
|
-
dr_sigmas = pencil_spread/sigma
|
|
678
|
-
|
|
679
|
-
# Generate 4D coordinates
|
|
680
|
-
if side == '+-':
|
|
681
|
-
num_plus = int(num_particles/2)
|
|
682
|
-
num_min = int(num_particles - num_plus)
|
|
683
|
-
coords_plus = self._generate_4D_pencil_one_jaw(num_plus, collimator, plane, '+',
|
|
684
|
-
impact_parameter, dr_sigmas,
|
|
685
|
-
transverse_spread_sigma, match_at_s)
|
|
686
|
-
coords_min = self._generate_4D_pencil_one_jaw(num_min, collimator, plane, '-',
|
|
687
|
-
impact_parameter, dr_sigmas,
|
|
688
|
-
transverse_spread_sigma, match_at_s)
|
|
689
|
-
coords = [ [*c_plus, *c_min] for c_plus, c_min in zip(coords_plus, coords_min)]
|
|
690
|
-
else:
|
|
691
|
-
coords = self._generate_4D_pencil_one_jaw(num_particles, collimator, plane, side,
|
|
692
|
-
impact_parameter, dr_sigmas,
|
|
693
|
-
transverse_spread_sigma, match_at_s)
|
|
694
|
-
pencil = coords[0]
|
|
695
|
-
p_pencil = coords[1]
|
|
696
|
-
transverse_norm = coords[2]
|
|
697
|
-
p_transverse_norm = coords[3]
|
|
698
|
-
|
|
699
|
-
# Longitudinal plane
|
|
700
|
-
# TODO: make this more general, make this better
|
|
701
|
-
if longitudinal is None:
|
|
702
|
-
delta = 0
|
|
703
|
-
zeta = 0
|
|
704
|
-
elif longitudinal == 'matched_dispersion':
|
|
705
|
-
if longitudinal_betatron_cut is None:
|
|
706
|
-
cut = 0
|
|
707
|
-
else:
|
|
708
|
-
cut = np.random.uniform(-longitudinal_betatron_cut, longitudinal_betatron_cut, num_particles)
|
|
709
|
-
delta = self.generate_delta_from_dispersion(at_element=collimator, plane=plane, position_mm=pencil,
|
|
710
|
-
betatron_cut=cut)
|
|
711
|
-
zeta = 0
|
|
712
|
-
elif longitudinal == 'bucket':
|
|
713
|
-
zeta, delta = xp.generate_longitudinal_coordinates(
|
|
714
|
-
num_particles=num_particles, distribution='gaussian', sigma_z=sigma_z, line=self.line
|
|
715
|
-
)
|
|
716
|
-
elif not hasattr(longitudinal, '__iter__'):
|
|
717
|
-
raise ValueError
|
|
718
|
-
elif len(longitudinal) != 2:
|
|
719
|
-
raise ValueError
|
|
720
|
-
elif isinstance(longitudinal, str):
|
|
721
|
-
raise ValueError
|
|
722
|
-
elif isinstance(longitudinal, dict):
|
|
723
|
-
zeta = longitudinal['zeta']
|
|
724
|
-
delta = longitudinal['delta']
|
|
725
|
-
else:
|
|
726
|
-
zeta = longitudinal[0]
|
|
727
|
-
delta = longitudinal[1]
|
|
728
|
-
|
|
729
|
-
# Build the particles
|
|
730
|
-
if plane == 'x':
|
|
731
|
-
part = xp.build_particles(
|
|
732
|
-
x=pencil, px=p_pencil, y_norm=transverse_norm, py_norm=p_transverse_norm,
|
|
733
|
-
zeta=zeta, delta=delta, nemitt_x=nemitt_x, nemitt_y=nemitt_y,
|
|
734
|
-
line=self.line, at_element=collimator, match_at_s=match_at_s,
|
|
735
|
-
_buffer=self._part_buffer
|
|
736
|
-
)
|
|
737
|
-
else:
|
|
738
|
-
part = xp.build_particles(
|
|
739
|
-
x_norm=transverse_norm, px_norm=p_transverse_norm, y=pencil, py=p_pencil,
|
|
740
|
-
zeta=zeta, delta=delta, nemitt_x=nemitt_x, nemitt_y=nemitt_y,
|
|
741
|
-
line=self.line, at_element=collimator, match_at_s=match_at_s,
|
|
742
|
-
_buffer=self._part_buffer
|
|
743
|
-
)
|
|
744
|
-
|
|
745
|
-
part._init_random_number_generator()
|
|
746
|
-
|
|
747
|
-
return part
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
def generate_delta_from_dispersion(self, at_element, *, plane, position_mm, betatron_cut=0):
|
|
751
|
-
line = self.line
|
|
752
|
-
if line.tracker is None:
|
|
753
|
-
raise ValueError("Need to build tracker first!")
|
|
754
|
-
if not hasattr(betatron_cut, '__iter__'):
|
|
755
|
-
if hasattr(position_mm, '__iter__'):
|
|
756
|
-
betatron_cut = np.full_like(position_mm, betatron_cut)
|
|
757
|
-
elif not hasattr(position_mm, '__iter__'):
|
|
758
|
-
position_mm = np.full_like(betatron_cut, position_mm)
|
|
759
|
-
elif len(position_mm) != len(betatron_cut):
|
|
760
|
-
raise ValueError
|
|
761
|
-
tw = line.twiss()
|
|
762
|
-
if isinstance(at_element, str):
|
|
763
|
-
idx = line.element_names.index(at_element)
|
|
764
|
-
betagamma = line.particle_ref.beta0[0] * line.particle_ref.gamma0[0]
|
|
765
|
-
if plane == 'x':
|
|
766
|
-
sigma = np.sqrt(tw.betx[idx]*self.colldb.emittance[0]/betagamma)
|
|
767
|
-
delta = (position_mm - betatron_cut*sigma - tw.x[idx]) / tw.dx[idx]
|
|
768
|
-
elif plane == 'y':
|
|
769
|
-
sigma = np.sqrt(tw.bety[idx]*self.colldb.emittance[1]/betagamma)
|
|
770
|
-
delta = (position_mm - betatron_cut*sigma - tw.y[idx]) / tw.dy[idx]
|
|
771
|
-
else:
|
|
772
|
-
raise ValueError("The variable 'plane' needs to be either 'x' or 'y'!")
|
|
773
|
-
return delta
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
def enable_scattering(self):
|
|
777
|
-
# Prepare collimators for tracking
|
|
778
|
-
for el in self.line.get_elements_of_type(element_classes)[0]:
|
|
779
|
-
el.enable_scattering()
|
|
780
|
-
self._set_record_impacts()
|
|
781
|
-
|
|
782
|
-
def disable_scattering(self):
|
|
783
|
-
# Prepare collimators for tracking
|
|
784
|
-
for el in self.line.get_elements_of_type(element_classes)[0]:
|
|
785
|
-
el.disable_scattering()
|
|
786
|
-
|
|
787
|
-
@property
|
|
788
|
-
def scattering_enabled(self):
|
|
789
|
-
all_enabled = np.all([self.line[coll]._tracking if hasattr(self.line[coll], '_tracking')
|
|
790
|
-
else True for coll in self.collimator_names])
|
|
791
|
-
some_enabled = np.any([self.line[coll]._tracking if hasattr(self.line[coll], '_tracking')
|
|
792
|
-
else True for coll in self.collimator_names])
|
|
793
|
-
if some_enabled and not all_enabled:
|
|
794
|
-
raise ValueError("Some collimators are enabled for tracking but not all! "
|
|
795
|
-
+ "This should not happen.")
|
|
796
|
-
return all_enabled
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
def summary(self, part, weights=None, show_zeros=False, file=None, recompute=False):
|
|
800
|
-
|
|
801
|
-
# We cache the result
|
|
802
|
-
if (self._summary is None or self._part is None
|
|
803
|
-
or not xt.line._dicts_equal(part.to_dict(), self._part)
|
|
804
|
-
or recompute
|
|
805
|
-
):
|
|
806
|
-
if weights is None:
|
|
807
|
-
weights = np.ones(len(part.x))
|
|
808
|
-
else:
|
|
809
|
-
part.sort(interleave_lost_particles=True)
|
|
810
|
-
self._part = part.to_dict()
|
|
811
|
-
coll_mask = (part.state<=-330) & (part.state>=-340)
|
|
812
|
-
coll_losses = np.array([self.line.element_names[i] for i in part.at_element[coll_mask]])
|
|
813
|
-
coll_loss_single = np.unique(coll_losses)
|
|
814
|
-
coll_lengths = [self.line[nn].active_length for nn in self.collimator_names]
|
|
815
|
-
coll_pos = [self.colldb.s_center[nn] for nn in self.collimator_names]
|
|
816
|
-
if self._line_is_reversed:
|
|
817
|
-
coll_pos = [self.machine_length - s for s in coll_pos ]
|
|
818
|
-
coll_types = [self.line[nn].__class__.__name__ for nn in self.collimator_names]
|
|
819
|
-
coll_weights = weights[coll_mask]
|
|
820
|
-
nabs = [coll_weights[coll_losses==nn].sum() for nn in self.collimator_names]
|
|
821
|
-
|
|
822
|
-
self._summary = pd.DataFrame({
|
|
823
|
-
"collname": self.collimator_names,
|
|
824
|
-
"nabs": nabs,
|
|
825
|
-
"length": coll_lengths,
|
|
826
|
-
"s": coll_pos,
|
|
827
|
-
"type": coll_types
|
|
828
|
-
})
|
|
829
|
-
|
|
830
|
-
if file is not None:
|
|
831
|
-
with open(Path(file), 'w') as fid:
|
|
832
|
-
fid.write(self._summary.__repr__())
|
|
833
|
-
|
|
834
|
-
if show_zeros:
|
|
835
|
-
return self._summary
|
|
836
|
-
else:
|
|
837
|
-
return self._summary[self._summary.nabs > 0]
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
def create_weights_from_initial_state(part, function):
|
|
841
|
-
if len(function) == 4:
|
|
842
|
-
return function[0](part.x)*function[1](part.px)*\
|
|
843
|
-
function[2](part.y)*function[3](part.py)
|
|
844
|
-
elif len(function) == 6:
|
|
845
|
-
return function[0](part.x)*function[1](part.px)*\
|
|
846
|
-
function[2](part.y)*function[3](part.py)*\
|
|
847
|
-
function[4](part.zeta)*function[5](part.delta)
|
|
848
|
-
else:
|
|
849
|
-
raise NotImplementedError
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
def lossmap(self, part, interpolation=0.1, file=None, recompute=False, weights=None):
|
|
853
|
-
|
|
854
|
-
# We cache the result
|
|
855
|
-
if (self._lossmap is None or self._part is None
|
|
856
|
-
or not xt.line._dicts_equal(part.to_dict(), self._part)
|
|
857
|
-
or recompute
|
|
858
|
-
):
|
|
859
|
-
|
|
860
|
-
self._part = part.to_dict()
|
|
861
|
-
|
|
862
|
-
# Loss location refinement
|
|
863
|
-
if interpolation is not None:
|
|
864
|
-
# We need to correct for particles scattered out of the collimator beyond the aperture restriction:
|
|
865
|
-
# TODO: this should be done in the scattering code!!!
|
|
866
|
-
new_state = part.state
|
|
867
|
-
new_elem = part.at_element
|
|
868
|
-
for idx, elem in enumerate(part.at_element):
|
|
869
|
-
if (part.state[idx]==0 and elem > 0 and
|
|
870
|
-
self.line.element_names[elem-1] in self.collimator_names
|
|
871
|
-
):
|
|
872
|
-
print(f"Found at {self.line.element_names[elem]}, should be {self.line.element_names[elem-1]}")
|
|
873
|
-
new_state[idx] = -339 # lost on collimator, special state ## TODO get the correct flag
|
|
874
|
-
new_elem[idx] = elem - 1
|
|
875
|
-
part.state = new_state
|
|
876
|
-
part.at_element = new_elem
|
|
877
|
-
# Do the interpolation
|
|
878
|
-
aper_s = list(part.s[part.state==0])
|
|
879
|
-
if len(aper_s) > 0:
|
|
880
|
-
print("Performing the aperture losses refinement.")
|
|
881
|
-
loss_loc_refinement = xt.LossLocationRefinement(self.line,
|
|
882
|
-
n_theta = 360, # Angular resolution in the polygonal approximation of the aperture
|
|
883
|
-
r_max = 0.5, # Maximum transverse aperture in m
|
|
884
|
-
dr = 50e-6, # Transverse loss refinement accuracy [m]
|
|
885
|
-
ds = interpolation, # Longitudinal loss refinement accuracy [m]
|
|
886
|
-
# save_refine_trackers=True # Diagnostics flag
|
|
887
|
-
)
|
|
888
|
-
loss_loc_refinement.refine_loss_location(part)
|
|
889
|
-
|
|
890
|
-
aper_s, aper_names, aper_nabs = self._get_aperture_losses(part, weights)
|
|
891
|
-
coll_summary = self.summary(part, weights, recompute=recompute, show_zeros=False).to_dict('list')
|
|
892
|
-
|
|
893
|
-
self._lossmap = {
|
|
894
|
-
'collimator': {
|
|
895
|
-
's': coll_summary['s'],
|
|
896
|
-
'name': coll_summary['collname'],
|
|
897
|
-
'length': coll_summary['length'],
|
|
898
|
-
'n': coll_summary['nabs']
|
|
899
|
-
}
|
|
900
|
-
,
|
|
901
|
-
'aperture': {
|
|
902
|
-
's': aper_s,
|
|
903
|
-
'name': aper_names,
|
|
904
|
-
'n': aper_nabs
|
|
905
|
-
}
|
|
906
|
-
,
|
|
907
|
-
'machine_length': self.machine_length
|
|
908
|
-
,
|
|
909
|
-
'interpolation': interpolation
|
|
910
|
-
,
|
|
911
|
-
'reversed': self._line_is_reversed
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
if file is not None:
|
|
915
|
-
with open(Path(file), 'w') as fid:
|
|
916
|
-
json.dump(self._lossmap, fid, cls=xo.JEncoder, indent=True)
|
|
917
|
-
|
|
918
|
-
return self._lossmap
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
def _get_aperture_losses(self, part, weights=None):
|
|
922
|
-
if weights is None:
|
|
923
|
-
weights = np.ones(len(part.x))
|
|
924
|
-
else:
|
|
925
|
-
part.sort(interleave_lost_particles=True)
|
|
926
|
-
|
|
927
|
-
# Get s position per particle (lost on aperture)
|
|
928
|
-
aper_mask = part.state==0
|
|
929
|
-
aper_s = list(part.s[aper_mask])
|
|
930
|
-
if len(aper_s) == 0:
|
|
931
|
-
return [], [], []
|
|
932
|
-
if self._line_is_reversed:
|
|
933
|
-
aper_s = [ self.machine_length - s for s in aper_s ]
|
|
934
|
-
|
|
935
|
-
# Store names of aperture markers
|
|
936
|
-
aper_names = [self.line.element_names[i] for i in part.at_element[aper_mask]]
|
|
937
|
-
name_dict = dict(zip(aper_s, aper_names)) # TODO: not floating-point-safe and slow
|
|
938
|
-
|
|
939
|
-
# Create output arrays
|
|
940
|
-
aper_pos = np.unique(aper_s)
|
|
941
|
-
aper_weights = weights[aper_mask]
|
|
942
|
-
aper_nabs = [aper_weights[aper_s==ss].sum() for ss in aper_pos] # TODO: this might be slow
|
|
943
|
-
aper_names = [name_dict[ss] for ss in aper_pos]
|
|
944
|
-
return aper_pos, aper_names, aper_nabs
|
|
945
|
-
|
|
10
|
+
raise ValueError("`CollimatorManager` is deprecated. Use `CollimatorDatabase` instead.")
|