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.

Files changed (350) hide show
  1. xcoll/__init__.py +13 -4
  2. xcoll/beam_elements/__init__.py +14 -6
  3. xcoll/beam_elements/absorber.py +41 -7
  4. xcoll/beam_elements/base.py +1202 -247
  5. xcoll/beam_elements/blowup.py +198 -0
  6. xcoll/beam_elements/elements_src/black_absorber.h +136 -0
  7. xcoll/beam_elements/elements_src/black_crystal.h +129 -0
  8. xcoll/beam_elements/elements_src/blowup.h +42 -0
  9. xcoll/beam_elements/elements_src/emittance_monitor.h +109 -0
  10. xcoll/beam_elements/{collimators_src → elements_src}/everest_block.h +59 -30
  11. xcoll/beam_elements/elements_src/everest_collimator.h +237 -0
  12. xcoll/beam_elements/elements_src/everest_crystal.h +280 -0
  13. xcoll/beam_elements/everest.py +65 -119
  14. xcoll/beam_elements/monitor.py +428 -0
  15. xcoll/colldb.py +276 -747
  16. xcoll/general.py +5 -5
  17. xcoll/headers/checks.h +1 -1
  18. xcoll/headers/particle_states.h +2 -2
  19. xcoll/initial_distribution.py +207 -0
  20. xcoll/install.py +179 -0
  21. xcoll/interaction_record/__init__.py +1 -0
  22. xcoll/interaction_record/interaction_record.py +298 -0
  23. xcoll/interaction_record/interaction_record_src/interaction_record.h +98 -0
  24. xcoll/{impacts → interaction_record}/interaction_types.py +11 -4
  25. xcoll/line_tools.py +82 -0
  26. xcoll/lossmap.py +219 -0
  27. xcoll/manager.py +2 -937
  28. xcoll/rf_sweep.py +1 -1
  29. xcoll/scattering_routines/everest/amorphous.h +232 -0
  30. xcoll/scattering_routines/everest/channeling.h +240 -0
  31. xcoll/scattering_routines/everest/crystal_parameters.h +137 -0
  32. xcoll/scattering_routines/everest/everest.h +11 -30
  33. xcoll/scattering_routines/everest/everest.py +13 -10
  34. xcoll/scattering_routines/everest/jaw.h +28 -197
  35. xcoll/scattering_routines/everest/materials.py +37 -15
  36. xcoll/scattering_routines/everest/multiple_coulomb_scattering.h +31 -10
  37. xcoll/scattering_routines/everest/nuclear_interaction.h +86 -0
  38. xcoll/scattering_routines/everest/properties.h +6 -1
  39. xcoll/scattering_routines/fluka/flukaio/lib/libFlukaIO64.a +0 -0
  40. xcoll/scattering_routines/geant4/collimasim/.git +1 -0
  41. xcoll/scattering_routines/geant4/collimasim/.gitignore +12 -0
  42. xcoll/scattering_routines/geant4/collimasim/.gitmodules +3 -0
  43. xcoll/scattering_routines/geant4/collimasim/CMakeLists.txt +26 -0
  44. xcoll/scattering_routines/geant4/collimasim/README.md +21 -0
  45. xcoll/scattering_routines/geant4/collimasim/docs/Makefile +20 -0
  46. xcoll/scattering_routines/geant4/collimasim/docs/make.bat +35 -0
  47. xcoll/scattering_routines/geant4/collimasim/docs/source/collimasim.rst +10 -0
  48. xcoll/scattering_routines/geant4/collimasim/docs/source/conf.py +59 -0
  49. xcoll/scattering_routines/geant4/collimasim/docs/source/index.rst +26 -0
  50. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.appveyor.yml +37 -0
  51. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.clang-format +19 -0
  52. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.clang-tidy +65 -0
  53. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.cmake-format.yaml +73 -0
  54. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.git +1 -0
  55. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/CODEOWNERS +9 -0
  56. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/CONTRIBUTING.md +386 -0
  57. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/ISSUE_TEMPLATE/bug-report.yml +45 -0
  58. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/ISSUE_TEMPLATE/config.yml +8 -0
  59. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/dependabot.yml +16 -0
  60. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/labeler.yml +8 -0
  61. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/labeler_merged.yml +3 -0
  62. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/pull_request_template.md +19 -0
  63. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/workflows/ci.yml +969 -0
  64. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/workflows/configure.yml +84 -0
  65. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/workflows/format.yml +48 -0
  66. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/workflows/labeler.yml +16 -0
  67. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/workflows/pip.yml +103 -0
  68. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.gitignore +45 -0
  69. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.pre-commit-config.yaml +151 -0
  70. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.readthedocs.yml +3 -0
  71. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/CMakeLists.txt +297 -0
  72. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/LICENSE +29 -0
  73. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/MANIFEST.in +6 -0
  74. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/README.rst +180 -0
  75. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/Doxyfile +23 -0
  76. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/Makefile +192 -0
  77. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/_static/theme_overrides.css +11 -0
  78. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/chrono.rst +81 -0
  79. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/custom.rst +93 -0
  80. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/eigen.rst +310 -0
  81. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/functional.rst +109 -0
  82. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/index.rst +43 -0
  83. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/overview.rst +171 -0
  84. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/stl.rst +251 -0
  85. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/strings.rst +305 -0
  86. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/classes.rst +1297 -0
  87. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/embedding.rst +262 -0
  88. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/exceptions.rst +396 -0
  89. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/functions.rst +568 -0
  90. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/misc.rst +337 -0
  91. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/pycpp/index.rst +13 -0
  92. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/pycpp/numpy.rst +463 -0
  93. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/pycpp/object.rst +286 -0
  94. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/pycpp/utilities.rst +155 -0
  95. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/smart_ptrs.rst +174 -0
  96. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/basics.rst +308 -0
  97. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/benchmark.py +91 -0
  98. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/benchmark.rst +95 -0
  99. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/changelog.rst +2050 -0
  100. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/classes.rst +542 -0
  101. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/cmake/index.rst +8 -0
  102. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/compiling.rst +648 -0
  103. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/conf.py +381 -0
  104. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/faq.rst +343 -0
  105. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/index.rst +48 -0
  106. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/installing.rst +105 -0
  107. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/limitations.rst +72 -0
  108. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/pybind11-logo.png +0 -0
  109. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/pybind11_vs_boost_python1.png +0 -0
  110. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/pybind11_vs_boost_python1.svg +427 -0
  111. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/pybind11_vs_boost_python2.png +0 -0
  112. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/pybind11_vs_boost_python2.svg +427 -0
  113. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/reference.rst +130 -0
  114. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/release.rst +96 -0
  115. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/requirements.txt +8 -0
  116. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/upgrade.rst +548 -0
  117. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/attr.h +605 -0
  118. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/buffer_info.h +144 -0
  119. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/cast.h +1432 -0
  120. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/chrono.h +213 -0
  121. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/common.h +2 -0
  122. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/complex.h +65 -0
  123. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/class.h +709 -0
  124. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/common.h +1021 -0
  125. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/descr.h +104 -0
  126. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/init.h +346 -0
  127. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/internals.h +467 -0
  128. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/type_caster_base.h +978 -0
  129. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/typeid.h +55 -0
  130. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/eigen.h +606 -0
  131. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/embed.h +284 -0
  132. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/eval.h +163 -0
  133. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/functional.h +121 -0
  134. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/gil.h +193 -0
  135. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/iostream.h +275 -0
  136. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/numpy.h +1741 -0
  137. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/operators.h +163 -0
  138. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/options.h +65 -0
  139. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/pybind11.h +2497 -0
  140. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/pytypes.h +1879 -0
  141. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/stl/filesystem.h +103 -0
  142. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/stl.h +375 -0
  143. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/stl_bind.h +747 -0
  144. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/noxfile.py +88 -0
  145. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/__init__.py +11 -0
  146. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/__main__.py +52 -0
  147. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/_version.py +12 -0
  148. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/_version.pyi +6 -0
  149. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/commands.py +21 -0
  150. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/py.typed +0 -0
  151. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/setup_helpers.py +482 -0
  152. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/setup_helpers.pyi +63 -0
  153. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pyproject.toml +41 -0
  154. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/setup.cfg +56 -0
  155. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/setup.py +155 -0
  156. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/CMakeLists.txt +503 -0
  157. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/conftest.py +208 -0
  158. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/constructor_stats.h +275 -0
  159. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/cross_module_gil_utils.cpp +73 -0
  160. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/env.py +33 -0
  161. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/extra_python_package/pytest.ini +0 -0
  162. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/extra_python_package/test_files.py +279 -0
  163. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/extra_setuptools/pytest.ini +0 -0
  164. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/extra_setuptools/test_setuphelper.py +143 -0
  165. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/local_bindings.h +85 -0
  166. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/object.h +179 -0
  167. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/pybind11_cross_module_tests.cpp +151 -0
  168. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/pybind11_tests.cpp +91 -0
  169. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/pybind11_tests.h +85 -0
  170. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/pytest.ini +19 -0
  171. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/requirements.txt +12 -0
  172. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_async.cpp +26 -0
  173. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_async.py +25 -0
  174. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_buffers.cpp +216 -0
  175. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_buffers.py +163 -0
  176. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_builtin_casters.cpp +286 -0
  177. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_builtin_casters.py +536 -0
  178. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_call_policies.cpp +107 -0
  179. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_call_policies.py +248 -0
  180. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_callbacks.cpp +227 -0
  181. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_callbacks.py +202 -0
  182. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_chrono.cpp +84 -0
  183. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_chrono.py +210 -0
  184. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_class.cpp +550 -0
  185. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_class.py +473 -0
  186. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/CMakeLists.txt +84 -0
  187. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/embed.cpp +21 -0
  188. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/installed_embed/CMakeLists.txt +28 -0
  189. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/installed_function/CMakeLists.txt +39 -0
  190. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/installed_target/CMakeLists.txt +46 -0
  191. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/main.cpp +6 -0
  192. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/subdirectory_embed/CMakeLists.txt +41 -0
  193. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/subdirectory_function/CMakeLists.txt +35 -0
  194. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/subdirectory_target/CMakeLists.txt +41 -0
  195. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/test.py +10 -0
  196. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_constants_and_functions.cpp +165 -0
  197. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_constants_and_functions.py +53 -0
  198. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_copy_move.cpp +238 -0
  199. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_copy_move.py +126 -0
  200. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_custom_type_casters.cpp +141 -0
  201. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_custom_type_casters.py +117 -0
  202. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_custom_type_setup.cpp +41 -0
  203. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_custom_type_setup.py +50 -0
  204. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_docstring_options.cpp +69 -0
  205. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_docstring_options.py +42 -0
  206. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_eigen.cpp +348 -0
  207. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_eigen.py +771 -0
  208. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_embed/CMakeLists.txt +47 -0
  209. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_embed/catch.cpp +22 -0
  210. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_embed/external_module.cpp +23 -0
  211. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_embed/test_interpreter.cpp +326 -0
  212. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_embed/test_interpreter.py +15 -0
  213. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_enum.cpp +148 -0
  214. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_enum.py +272 -0
  215. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_eval.cpp +119 -0
  216. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_eval.py +51 -0
  217. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_eval_call.py +5 -0
  218. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_exceptions.cpp +285 -0
  219. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_exceptions.h +12 -0
  220. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_exceptions.py +265 -0
  221. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_factory_constructors.cpp +397 -0
  222. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_factory_constructors.py +520 -0
  223. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_gil_scoped.cpp +49 -0
  224. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_gil_scoped.py +94 -0
  225. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_iostream.cpp +125 -0
  226. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_iostream.py +331 -0
  227. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_kwargs_and_defaults.cpp +153 -0
  228. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_kwargs_and_defaults.py +284 -0
  229. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_local_bindings.cpp +107 -0
  230. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_local_bindings.py +257 -0
  231. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_methods_and_attributes.cpp +412 -0
  232. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_methods_and_attributes.py +517 -0
  233. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_modules.cpp +102 -0
  234. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_modules.py +92 -0
  235. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_multiple_inheritance.cpp +233 -0
  236. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_multiple_inheritance.py +360 -0
  237. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_numpy_array.cpp +472 -0
  238. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_numpy_array.py +593 -0
  239. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_numpy_dtypes.cpp +524 -0
  240. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_numpy_dtypes.py +441 -0
  241. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_numpy_vectorize.cpp +103 -0
  242. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_numpy_vectorize.py +267 -0
  243. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_opaque_types.cpp +73 -0
  244. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_opaque_types.py +59 -0
  245. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_operator_overloading.cpp +235 -0
  246. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_operator_overloading.py +146 -0
  247. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_pickling.cpp +189 -0
  248. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_pickling.py +82 -0
  249. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_pytypes.cpp +560 -0
  250. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_pytypes.py +651 -0
  251. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_sequences_and_iterators.cpp +500 -0
  252. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_sequences_and_iterators.py +253 -0
  253. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_smart_ptr.cpp +452 -0
  254. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_smart_ptr.py +318 -0
  255. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_stl.cpp +342 -0
  256. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_stl.py +291 -0
  257. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_stl_binders.cpp +131 -0
  258. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_stl_binders.py +318 -0
  259. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_tagbased_polymorphic.cpp +144 -0
  260. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_tagbased_polymorphic.py +29 -0
  261. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_thread.cpp +66 -0
  262. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_thread.py +44 -0
  263. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_union.cpp +22 -0
  264. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_union.py +9 -0
  265. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_virtual_functions.cpp +510 -0
  266. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_virtual_functions.py +408 -0
  267. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/valgrind-numpy-scipy.supp +140 -0
  268. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/valgrind-python.supp +117 -0
  269. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/FindCatch.cmake +70 -0
  270. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/FindEigen3.cmake +86 -0
  271. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/FindPythonLibsNew.cmake +257 -0
  272. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/check-style.sh +44 -0
  273. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/cmake_uninstall.cmake.in +23 -0
  274. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/libsize.py +39 -0
  275. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/make_changelog.py +64 -0
  276. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/pybind11Common.cmake +402 -0
  277. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/pybind11Config.cmake.in +233 -0
  278. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/pybind11NewTools.cmake +276 -0
  279. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/pybind11Tools.cmake +214 -0
  280. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/pyproject.toml +3 -0
  281. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/setup_global.py.in +65 -0
  282. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/setup_main.py.in +41 -0
  283. xcoll/scattering_routines/geant4/collimasim/pyproject.toml +8 -0
  284. xcoll/scattering_routines/geant4/collimasim/setup.py +144 -0
  285. xcoll/scattering_routines/geant4/collimasim/src/collimasim/BDSPyATInterface.cpp +403 -0
  286. xcoll/scattering_routines/geant4/collimasim/src/collimasim/BDSPyATInterface.hh +100 -0
  287. xcoll/scattering_routines/geant4/collimasim/src/collimasim/BDSXtrackInterface.cpp +763 -0
  288. xcoll/scattering_routines/geant4/collimasim/src/collimasim/BDSXtrackInterface.hh +118 -0
  289. xcoll/scattering_routines/geant4/collimasim/src/collimasim/__init__.py +8 -0
  290. xcoll/scattering_routines/geant4/collimasim/src/collimasim/bindings.cpp +63 -0
  291. xcoll/scattering_routines/geant4/collimasim/src/collimasim/pyCollimatorPass.py +142 -0
  292. xcoll/scattering_routines/geant4/collimasim/src/collimasim/xtrack_collimator.py +556 -0
  293. xcoll/scattering_routines/geant4/collimasim/src/collimasim.egg-info/PKG-INFO +6 -0
  294. xcoll/scattering_routines/geant4/collimasim/src/collimasim.egg-info/SOURCES.txt +24 -0
  295. xcoll/scattering_routines/geant4/collimasim/src/collimasim.egg-info/dependency_links.txt +1 -0
  296. xcoll/scattering_routines/geant4/collimasim/src/collimasim.egg-info/not-zip-safe +1 -0
  297. xcoll/scattering_routines/geant4/collimasim/src/collimasim.egg-info/top_level.txt +1 -0
  298. xcoll/scattering_routines/geant4/collimasim/tests/README.md +25 -0
  299. xcoll/scattering_routines/geant4/collimasim/tests/resources/CollDB_forions.dat +25 -0
  300. xcoll/scattering_routines/geant4/collimasim/tests/resources/CollDB_new_example.dat +18 -0
  301. xcoll/scattering_routines/geant4/collimasim/tests/resources/CollDB_old_example.dat +68 -0
  302. xcoll/scattering_routines/geant4/collimasim/tests/resources/CollDB_testing.dat +15 -0
  303. xcoll/scattering_routines/geant4/collimasim/tests/resources/CollDB_yaml_example.yaml +110 -0
  304. xcoll/scattering_routines/geant4/collimasim/tests/resources/collgaps.dat +7 -0
  305. xcoll/scattering_routines/geant4/collimasim/tests/resources/collgaps_pyat_test.dat +3 -0
  306. xcoll/scattering_routines/geant4/collimasim/tests/resources/collonly_twiss_file_example.tfs +54 -0
  307. xcoll/scattering_routines/geant4/collimasim/tests/resources/settings.gmad +3 -0
  308. xcoll/scattering_routines/geant4/collimasim/tests/resources/settings_black_absorber.gmad +3 -0
  309. xcoll/scattering_routines/geant4/collimasim/tests/resources/settings_ions.gmad +5 -0
  310. xcoll/scattering_routines/geant4/collimasim/tests/resources/twiss_file_testing.tfs +51 -0
  311. xcoll/scattering_routines/geant4/collimasim/tests/test_pyat.py +65 -0
  312. xcoll/scattering_routines/geant4/collimasim/tests/test_pyat_passmethod.py +59 -0
  313. xcoll/scattering_routines/geant4/collimasim/tests/test_pyat_tracking.py +102 -0
  314. xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack.py +75 -0
  315. xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_angle.py +74 -0
  316. xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_colldb_load.py +84 -0
  317. xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_interaction.py +159 -0
  318. xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_interaction_ion.py +99 -0
  319. xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_ions.py +78 -0
  320. xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_lost_energy.py +88 -0
  321. xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_tilt.py +80 -0
  322. xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_tracking.py +97 -0
  323. xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_tracking_ions.py +96 -0
  324. xcoll/scattering_routines/geometry/__init__.py +6 -0
  325. xcoll/scattering_routines/geometry/collimator_geometry.h +218 -0
  326. xcoll/scattering_routines/geometry/crystal_geometry.h +153 -0
  327. xcoll/scattering_routines/geometry/geometry.py +26 -0
  328. xcoll/scattering_routines/geometry/get_s.h +92 -0
  329. xcoll/scattering_routines/geometry/methods.h +111 -0
  330. xcoll/scattering_routines/geometry/objects.h +154 -0
  331. xcoll/scattering_routines/geometry/rotation.h +23 -0
  332. xcoll/scattering_routines/geometry/segments.h +226 -0
  333. xcoll/scattering_routines/geometry/sort.h +184 -0
  334. {xcoll-0.3.6.dist-info → xcoll-0.5.0.dist-info}/METADATA +1 -1
  335. xcoll-0.5.0.dist-info/RECORD +413 -0
  336. xcoll/beam_elements/collimators_src/absorber.h +0 -141
  337. xcoll/beam_elements/collimators_src/everest_collimator.h +0 -142
  338. xcoll/beam_elements/collimators_src/everest_crystal.h +0 -115
  339. xcoll/collimator_settings.py +0 -457
  340. xcoll/impacts/__init__.py +0 -1
  341. xcoll/impacts/impacts.py +0 -102
  342. xcoll/impacts/impacts_src/impacts.h +0 -99
  343. xcoll/scattering_routines/everest/crystal.h +0 -1302
  344. xcoll/scattering_routines/everest/scatter.h +0 -169
  345. xcoll/scattering_routines/everest/scatter_crystal.h +0 -260
  346. xcoll/scattering_routines/fluka/build_fluka_input.py +0 -58
  347. xcoll-0.3.6.dist-info/RECORD +0 -111
  348. {xcoll-0.3.6.dist-info → xcoll-0.5.0.dist-info}/LICENSE +0 -0
  349. {xcoll-0.3.6.dist-info → xcoll-0.5.0.dist-info}/NOTICE +0 -0
  350. {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, 2023. #
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
- # Get all arguments
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.")