xcoll 0.5.11__py3-none-any.whl → 0.6.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 (333) hide show
  1. xcoll/__init__.py +5 -18
  2. xcoll/beam_elements/__init__.py +1 -0
  3. xcoll/beam_elements/absorber.py +12 -2
  4. xcoll/beam_elements/base.py +162 -62
  5. xcoll/beam_elements/blowup.py +1 -0
  6. xcoll/beam_elements/elements_src/black_absorber.h +57 -58
  7. xcoll/beam_elements/elements_src/black_crystal.h +49 -50
  8. xcoll/beam_elements/elements_src/everest_block.h +21 -11
  9. xcoll/beam_elements/elements_src/everest_collimator.h +100 -91
  10. xcoll/beam_elements/elements_src/everest_crystal.h +145 -140
  11. xcoll/beam_elements/elements_src/transparent_collimator.h +126 -0
  12. xcoll/beam_elements/elements_src/transparent_crystal.h +118 -0
  13. xcoll/beam_elements/everest.py +16 -5
  14. xcoll/beam_elements/monitor.py +1 -0
  15. xcoll/beam_elements/transparent.py +83 -0
  16. xcoll/colldb.py +15 -6
  17. xcoll/general.py +1 -1
  18. xcoll/headers/particle_states.py +51 -0
  19. xcoll/initial_distribution.py +129 -103
  20. xcoll/interaction_record/interaction_record.py +2 -1
  21. xcoll/interaction_record/interaction_types.py +2 -2
  22. xcoll/line_tools.py +163 -74
  23. xcoll/lossmap.py +519 -127
  24. xcoll/plot.py +109 -0
  25. xcoll/rf_sweep.py +6 -0
  26. xcoll/scattering_routines/engine.py +600 -0
  27. xcoll/scattering_routines/environment.py +297 -0
  28. xcoll/scattering_routines/everest/amorphous.h +95 -71
  29. xcoll/scattering_routines/everest/{channeling.h → channelling.h} +121 -112
  30. xcoll/scattering_routines/everest/constants.h +1 -1
  31. xcoll/scattering_routines/everest/crystal_parameters.h +9 -9
  32. xcoll/scattering_routines/everest/everest.h +8 -3
  33. xcoll/scattering_routines/everest/everest.py +2 -1
  34. xcoll/scattering_routines/everest/ionisation_loss.h +141 -0
  35. xcoll/scattering_routines/everest/jaw.h +19 -24
  36. xcoll/scattering_routines/everest/materials.py +2 -0
  37. xcoll/scattering_routines/everest/multiple_coulomb_scattering.h +2 -2
  38. xcoll/scattering_routines/everest/nuclear_interaction.h +35 -19
  39. xcoll/scattering_routines/everest/properties.h +4 -73
  40. xcoll/xaux.py +73 -0
  41. {xcoll-0.5.11.dist-info → xcoll-0.6.0.dist-info}/METADATA +5 -5
  42. xcoll-0.6.0.dist-info/RECORD +135 -0
  43. xcoll/_manager.py +0 -22
  44. xcoll/headers/particle_states.h +0 -25
  45. xcoll/install.py +0 -35
  46. xcoll/scattering_routines/geant4/collimasim/.git +0 -1
  47. xcoll/scattering_routines/geant4/collimasim/.gitignore +0 -12
  48. xcoll/scattering_routines/geant4/collimasim/.gitmodules +0 -3
  49. xcoll/scattering_routines/geant4/collimasim/CMakeLists.txt +0 -26
  50. xcoll/scattering_routines/geant4/collimasim/README.md +0 -21
  51. xcoll/scattering_routines/geant4/collimasim/docs/Makefile +0 -20
  52. xcoll/scattering_routines/geant4/collimasim/docs/make.bat +0 -35
  53. xcoll/scattering_routines/geant4/collimasim/docs/source/collimasim.rst +0 -10
  54. xcoll/scattering_routines/geant4/collimasim/docs/source/conf.py +0 -59
  55. xcoll/scattering_routines/geant4/collimasim/docs/source/index.rst +0 -26
  56. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.appveyor.yml +0 -37
  57. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.clang-format +0 -19
  58. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.clang-tidy +0 -65
  59. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.cmake-format.yaml +0 -73
  60. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.git +0 -1
  61. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/CODEOWNERS +0 -9
  62. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/CONTRIBUTING.md +0 -386
  63. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/ISSUE_TEMPLATE/bug-report.yml +0 -45
  64. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/ISSUE_TEMPLATE/config.yml +0 -8
  65. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/dependabot.yml +0 -16
  66. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/labeler.yml +0 -8
  67. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/labeler_merged.yml +0 -3
  68. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/pull_request_template.md +0 -19
  69. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/workflows/ci.yml +0 -969
  70. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/workflows/configure.yml +0 -84
  71. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/workflows/format.yml +0 -48
  72. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/workflows/labeler.yml +0 -16
  73. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.github/workflows/pip.yml +0 -103
  74. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.gitignore +0 -45
  75. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.pre-commit-config.yaml +0 -151
  76. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/.readthedocs.yml +0 -3
  77. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/CMakeLists.txt +0 -297
  78. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/LICENSE +0 -29
  79. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/MANIFEST.in +0 -6
  80. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/README.rst +0 -180
  81. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/Doxyfile +0 -23
  82. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/Makefile +0 -192
  83. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/_static/theme_overrides.css +0 -11
  84. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/chrono.rst +0 -81
  85. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/custom.rst +0 -93
  86. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/eigen.rst +0 -310
  87. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/functional.rst +0 -109
  88. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/index.rst +0 -43
  89. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/overview.rst +0 -171
  90. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/stl.rst +0 -251
  91. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/cast/strings.rst +0 -305
  92. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/classes.rst +0 -1297
  93. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/embedding.rst +0 -262
  94. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/exceptions.rst +0 -396
  95. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/functions.rst +0 -568
  96. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/misc.rst +0 -337
  97. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/pycpp/index.rst +0 -13
  98. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/pycpp/numpy.rst +0 -463
  99. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/pycpp/object.rst +0 -286
  100. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/pycpp/utilities.rst +0 -155
  101. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/advanced/smart_ptrs.rst +0 -174
  102. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/basics.rst +0 -308
  103. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/benchmark.py +0 -91
  104. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/benchmark.rst +0 -95
  105. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/changelog.rst +0 -2050
  106. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/classes.rst +0 -542
  107. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/cmake/index.rst +0 -8
  108. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/compiling.rst +0 -648
  109. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/conf.py +0 -381
  110. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/faq.rst +0 -343
  111. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/index.rst +0 -48
  112. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/installing.rst +0 -105
  113. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/limitations.rst +0 -72
  114. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/pybind11-logo.png +0 -0
  115. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/pybind11_vs_boost_python1.png +0 -0
  116. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/pybind11_vs_boost_python1.svg +0 -427
  117. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/pybind11_vs_boost_python2.png +0 -0
  118. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/pybind11_vs_boost_python2.svg +0 -427
  119. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/reference.rst +0 -130
  120. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/release.rst +0 -96
  121. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/requirements.txt +0 -8
  122. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/docs/upgrade.rst +0 -548
  123. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/attr.h +0 -605
  124. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/buffer_info.h +0 -144
  125. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/cast.h +0 -1432
  126. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/chrono.h +0 -213
  127. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/common.h +0 -2
  128. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/complex.h +0 -65
  129. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/class.h +0 -709
  130. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/common.h +0 -1021
  131. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/descr.h +0 -104
  132. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/init.h +0 -346
  133. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/internals.h +0 -467
  134. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/type_caster_base.h +0 -978
  135. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/detail/typeid.h +0 -55
  136. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/eigen.h +0 -606
  137. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/embed.h +0 -284
  138. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/eval.h +0 -163
  139. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/functional.h +0 -121
  140. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/gil.h +0 -193
  141. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/iostream.h +0 -275
  142. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/numpy.h +0 -1741
  143. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/operators.h +0 -163
  144. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/options.h +0 -65
  145. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/pybind11.h +0 -2497
  146. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/pytypes.h +0 -1879
  147. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/stl/filesystem.h +0 -103
  148. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/stl.h +0 -375
  149. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/include/pybind11/stl_bind.h +0 -747
  150. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/noxfile.py +0 -88
  151. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/__init__.py +0 -11
  152. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/__main__.py +0 -52
  153. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/_version.py +0 -12
  154. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/_version.pyi +0 -6
  155. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/commands.py +0 -21
  156. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/py.typed +0 -0
  157. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/setup_helpers.py +0 -482
  158. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pybind11/setup_helpers.pyi +0 -63
  159. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/pyproject.toml +0 -41
  160. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/setup.cfg +0 -56
  161. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/setup.py +0 -155
  162. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/CMakeLists.txt +0 -503
  163. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/conftest.py +0 -208
  164. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/constructor_stats.h +0 -275
  165. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/cross_module_gil_utils.cpp +0 -73
  166. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/env.py +0 -33
  167. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/extra_python_package/pytest.ini +0 -0
  168. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/extra_python_package/test_files.py +0 -279
  169. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/extra_setuptools/pytest.ini +0 -0
  170. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/extra_setuptools/test_setuphelper.py +0 -143
  171. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/local_bindings.h +0 -85
  172. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/object.h +0 -179
  173. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/pybind11_cross_module_tests.cpp +0 -151
  174. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/pybind11_tests.cpp +0 -91
  175. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/pybind11_tests.h +0 -85
  176. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/pytest.ini +0 -19
  177. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/requirements.txt +0 -12
  178. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_async.cpp +0 -26
  179. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_async.py +0 -25
  180. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_buffers.cpp +0 -216
  181. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_buffers.py +0 -163
  182. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_builtin_casters.cpp +0 -286
  183. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_builtin_casters.py +0 -536
  184. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_call_policies.cpp +0 -107
  185. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_call_policies.py +0 -248
  186. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_callbacks.cpp +0 -227
  187. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_callbacks.py +0 -202
  188. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_chrono.cpp +0 -84
  189. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_chrono.py +0 -210
  190. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_class.cpp +0 -550
  191. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_class.py +0 -473
  192. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/CMakeLists.txt +0 -84
  193. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/embed.cpp +0 -21
  194. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/installed_embed/CMakeLists.txt +0 -28
  195. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/installed_function/CMakeLists.txt +0 -39
  196. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/installed_target/CMakeLists.txt +0 -46
  197. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/main.cpp +0 -6
  198. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/subdirectory_embed/CMakeLists.txt +0 -41
  199. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/subdirectory_function/CMakeLists.txt +0 -35
  200. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/subdirectory_target/CMakeLists.txt +0 -41
  201. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_cmake_build/test.py +0 -10
  202. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_constants_and_functions.cpp +0 -165
  203. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_constants_and_functions.py +0 -53
  204. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_copy_move.cpp +0 -238
  205. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_copy_move.py +0 -126
  206. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_custom_type_casters.cpp +0 -141
  207. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_custom_type_casters.py +0 -117
  208. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_custom_type_setup.cpp +0 -41
  209. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_custom_type_setup.py +0 -50
  210. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_docstring_options.cpp +0 -69
  211. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_docstring_options.py +0 -42
  212. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_eigen.cpp +0 -348
  213. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_eigen.py +0 -771
  214. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_embed/CMakeLists.txt +0 -47
  215. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_embed/catch.cpp +0 -22
  216. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_embed/external_module.cpp +0 -23
  217. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_embed/test_interpreter.cpp +0 -326
  218. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_embed/test_interpreter.py +0 -15
  219. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_enum.cpp +0 -148
  220. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_enum.py +0 -272
  221. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_eval.cpp +0 -119
  222. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_eval.py +0 -51
  223. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_eval_call.py +0 -5
  224. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_exceptions.cpp +0 -285
  225. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_exceptions.h +0 -12
  226. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_exceptions.py +0 -265
  227. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_factory_constructors.cpp +0 -397
  228. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_factory_constructors.py +0 -520
  229. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_gil_scoped.cpp +0 -49
  230. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_gil_scoped.py +0 -94
  231. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_iostream.cpp +0 -125
  232. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_iostream.py +0 -331
  233. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_kwargs_and_defaults.cpp +0 -153
  234. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_kwargs_and_defaults.py +0 -284
  235. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_local_bindings.cpp +0 -107
  236. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_local_bindings.py +0 -257
  237. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_methods_and_attributes.cpp +0 -412
  238. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_methods_and_attributes.py +0 -517
  239. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_modules.cpp +0 -102
  240. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_modules.py +0 -92
  241. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_multiple_inheritance.cpp +0 -233
  242. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_multiple_inheritance.py +0 -360
  243. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_numpy_array.cpp +0 -472
  244. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_numpy_array.py +0 -593
  245. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_numpy_dtypes.cpp +0 -524
  246. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_numpy_dtypes.py +0 -441
  247. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_numpy_vectorize.cpp +0 -103
  248. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_numpy_vectorize.py +0 -267
  249. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_opaque_types.cpp +0 -73
  250. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_opaque_types.py +0 -59
  251. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_operator_overloading.cpp +0 -235
  252. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_operator_overloading.py +0 -146
  253. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_pickling.cpp +0 -189
  254. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_pickling.py +0 -82
  255. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_pytypes.cpp +0 -560
  256. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_pytypes.py +0 -651
  257. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_sequences_and_iterators.cpp +0 -500
  258. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_sequences_and_iterators.py +0 -253
  259. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_smart_ptr.cpp +0 -452
  260. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_smart_ptr.py +0 -318
  261. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_stl.cpp +0 -342
  262. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_stl.py +0 -291
  263. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_stl_binders.cpp +0 -131
  264. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_stl_binders.py +0 -318
  265. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_tagbased_polymorphic.cpp +0 -144
  266. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_tagbased_polymorphic.py +0 -29
  267. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_thread.cpp +0 -66
  268. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_thread.py +0 -44
  269. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_union.cpp +0 -22
  270. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_union.py +0 -9
  271. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_virtual_functions.cpp +0 -510
  272. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/test_virtual_functions.py +0 -408
  273. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/valgrind-numpy-scipy.supp +0 -140
  274. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tests/valgrind-python.supp +0 -117
  275. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/FindCatch.cmake +0 -70
  276. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/FindEigen3.cmake +0 -86
  277. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/FindPythonLibsNew.cmake +0 -257
  278. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/check-style.sh +0 -44
  279. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/cmake_uninstall.cmake.in +0 -23
  280. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/libsize.py +0 -39
  281. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/make_changelog.py +0 -64
  282. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/pybind11Common.cmake +0 -402
  283. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/pybind11Config.cmake.in +0 -233
  284. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/pybind11NewTools.cmake +0 -276
  285. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/pybind11Tools.cmake +0 -214
  286. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/pyproject.toml +0 -3
  287. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/setup_global.py.in +0 -65
  288. xcoll/scattering_routines/geant4/collimasim/lib/pybind11/tools/setup_main.py.in +0 -41
  289. xcoll/scattering_routines/geant4/collimasim/pyproject.toml +0 -8
  290. xcoll/scattering_routines/geant4/collimasim/setup.py +0 -144
  291. xcoll/scattering_routines/geant4/collimasim/src/collimasim/BDSPyATInterface.cpp +0 -403
  292. xcoll/scattering_routines/geant4/collimasim/src/collimasim/BDSPyATInterface.hh +0 -100
  293. xcoll/scattering_routines/geant4/collimasim/src/collimasim/BDSXtrackInterface.cpp +0 -763
  294. xcoll/scattering_routines/geant4/collimasim/src/collimasim/BDSXtrackInterface.hh +0 -118
  295. xcoll/scattering_routines/geant4/collimasim/src/collimasim/__init__.py +0 -8
  296. xcoll/scattering_routines/geant4/collimasim/src/collimasim/bindings.cpp +0 -63
  297. xcoll/scattering_routines/geant4/collimasim/src/collimasim/pyCollimatorPass.py +0 -142
  298. xcoll/scattering_routines/geant4/collimasim/src/collimasim/xtrack_collimator.py +0 -556
  299. xcoll/scattering_routines/geant4/collimasim/src/collimasim.egg-info/PKG-INFO +0 -6
  300. xcoll/scattering_routines/geant4/collimasim/src/collimasim.egg-info/SOURCES.txt +0 -24
  301. xcoll/scattering_routines/geant4/collimasim/src/collimasim.egg-info/dependency_links.txt +0 -1
  302. xcoll/scattering_routines/geant4/collimasim/src/collimasim.egg-info/not-zip-safe +0 -1
  303. xcoll/scattering_routines/geant4/collimasim/src/collimasim.egg-info/top_level.txt +0 -1
  304. xcoll/scattering_routines/geant4/collimasim/tests/README.md +0 -25
  305. xcoll/scattering_routines/geant4/collimasim/tests/resources/CollDB_forions.dat +0 -25
  306. xcoll/scattering_routines/geant4/collimasim/tests/resources/CollDB_new_example.dat +0 -18
  307. xcoll/scattering_routines/geant4/collimasim/tests/resources/CollDB_old_example.dat +0 -68
  308. xcoll/scattering_routines/geant4/collimasim/tests/resources/CollDB_testing.dat +0 -15
  309. xcoll/scattering_routines/geant4/collimasim/tests/resources/CollDB_yaml_example.yaml +0 -110
  310. xcoll/scattering_routines/geant4/collimasim/tests/resources/collgaps.dat +0 -7
  311. xcoll/scattering_routines/geant4/collimasim/tests/resources/collgaps_pyat_test.dat +0 -3
  312. xcoll/scattering_routines/geant4/collimasim/tests/resources/collonly_twiss_file_example.tfs +0 -54
  313. xcoll/scattering_routines/geant4/collimasim/tests/resources/settings.gmad +0 -3
  314. xcoll/scattering_routines/geant4/collimasim/tests/resources/settings_black_absorber.gmad +0 -3
  315. xcoll/scattering_routines/geant4/collimasim/tests/resources/settings_ions.gmad +0 -5
  316. xcoll/scattering_routines/geant4/collimasim/tests/resources/twiss_file_testing.tfs +0 -51
  317. xcoll/scattering_routines/geant4/collimasim/tests/test_pyat.py +0 -65
  318. xcoll/scattering_routines/geant4/collimasim/tests/test_pyat_passmethod.py +0 -59
  319. xcoll/scattering_routines/geant4/collimasim/tests/test_pyat_tracking.py +0 -102
  320. xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack.py +0 -75
  321. xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_angle.py +0 -74
  322. xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_colldb_load.py +0 -84
  323. xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_interaction.py +0 -159
  324. xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_interaction_ion.py +0 -99
  325. xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_ions.py +0 -78
  326. xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_lost_energy.py +0 -88
  327. xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_tilt.py +0 -80
  328. xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_tracking.py +0 -97
  329. xcoll/scattering_routines/geant4/collimasim/tests/test_xtrack_tracking_ions.py +0 -96
  330. xcoll-0.5.11.dist-info/RECORD +0 -413
  331. {xcoll-0.5.11.dist-info → xcoll-0.6.0.dist-info}/LICENSE +0 -0
  332. {xcoll-0.5.11.dist-info → xcoll-0.6.0.dist-info}/NOTICE +0 -0
  333. {xcoll-0.5.11.dist-info → xcoll-0.6.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,600 @@
1
+ # copyright ############################### #
2
+ # This file is part of the Xcoll Package. #
3
+ # Copyright (c) CERN, 2025. #
4
+ # ######################################### #
5
+
6
+ import os
7
+ import numpy as np
8
+ from numbers import Number
9
+ from functools import wraps
10
+
11
+ import xobjects as xo
12
+ import xtrack as xt
13
+ import xtrack.particles.pdg as pdg
14
+
15
+ try:
16
+ # TODO: once xaux is in Xsuite keep only this
17
+ from xaux import FsPath, ranID
18
+ except (ImportError, ModuleNotFoundError):
19
+ from ..xaux import FsPath, ranID
20
+
21
+
22
+ class BaseEngine(xo.HybridClass):
23
+ _xofields = {
24
+ '_particle_ref': xt.Particles._XoStruct,
25
+ '_seed': xo.UInt64,
26
+ '_capacity': xo.Int64,
27
+ }
28
+
29
+ _int32 = False
30
+ _only_protons = False
31
+ _element_classes = None
32
+ _uses_input_file = False
33
+ _num_input_files = 0
34
+ _uses_run_folder = False
35
+
36
+ def __init__(self, **kwargs):
37
+ if self._element_classes is None:
38
+ raise NotImplementedError(f"{self.__class__.__name__} needs to define `_element_classes`!")
39
+ # Initialise defaults
40
+ self._cwd = None
41
+ self._line = None
42
+ self._verbose = False
43
+ self._input_file = None
44
+ self._element_dict = {}
45
+ self._warning_given = False
46
+ self._environment = None
47
+ self._element_index = 0
48
+ self._tracking_initialised = False
49
+ self._deactivated_elements = {}
50
+ kwargs.setdefault('_particle_ref', xt.Particles())
51
+ kwargs.setdefault('_seed', 0)
52
+ kwargs.setdefault('_capacity', 0)
53
+ super().__init__(**kwargs)
54
+
55
+ def __del__(self, *args, **kwargs):
56
+ self.stop(warn=False)
57
+
58
+ def _warn(self, error=None):
59
+ if not self._warning_given:
60
+ print(f"Warning: Failed to import {self.__class__.__name__} environment "
61
+ + f"(did you compile?).\n{self.name.capitalize()} elements can be installed "
62
+ + f"but are not trackable.", flush=True)
63
+ if error:
64
+ print(f"Error: {error}", flush=True)
65
+ self._warning_given = True
66
+ self.stop()
67
+ if error:
68
+ raise error
69
+
70
+ def _print(self, *args, **kwargs):
71
+ if self.verbose:
72
+ kwargs.setdefault('flush', True)
73
+ print(*args, **kwargs)
74
+
75
+
76
+ # ==================
77
+ # === Properties ===
78
+ # ==================
79
+
80
+ @property
81
+ def environment(self):
82
+ return self._environment
83
+
84
+ @property
85
+ def name(self):
86
+ return self.__class__.__name__.replace('Engine', '').lower()
87
+
88
+ @property
89
+ def verbose(self):
90
+ return self._verbose
91
+
92
+ @verbose.setter
93
+ def verbose(self, val):
94
+ self._verbose = val
95
+
96
+ @property
97
+ def line(self):
98
+ return self._line
99
+
100
+ @line.setter
101
+ def line(self, val):
102
+ if not val is None and not isinstance(val, xt.Line):
103
+ raise ValueError("`line` has to be an xt.Line object!")
104
+ self._line = val
105
+
106
+ @line.deleter
107
+ def line(self):
108
+ self._line = None
109
+
110
+ @property
111
+ def particle_ref(self):
112
+ initial = xt.Particles().to_dict()
113
+ current = self._particle_ref.to_dict()
114
+ if xt.line._dicts_equal(initial, current):
115
+ return None
116
+ else:
117
+ return self._particle_ref
118
+
119
+ @particle_ref.setter
120
+ def particle_ref(self, val):
121
+ if val is None:
122
+ self._particle_ref = xt.Particles()
123
+ else:
124
+ if not isinstance(val, xt.Particles):
125
+ raise ValueError("`particle_ref` has to be an xt.Particles object!")
126
+ if val._capacity > 1:
127
+ raise ValueError("`particle_ref` has to be a single particle!")
128
+ pdg_id = val.pdg_id[0]
129
+ if pdg_id == 0:
130
+ if self._only_protons:
131
+ pdg_id = pdg.get_pdg_id_from_name('proton')
132
+ else:
133
+ raise ValueError(f"{self.__class__.__name__} allows the use of particles "
134
+ + f"different than protons. Hence, `particle_ref` "
135
+ + f"needs to have a valid pdg_id.")
136
+ elif self._only_protons and pdg_id != pdg.get_pdg_id_from_name('proton'):
137
+ raise ValueError("{self.__class__.__name__} only supports protons!")
138
+ self._particle_ref = val
139
+ self._particle_ref.pdg_id[0] = pdg_id
140
+
141
+ @particle_ref.deleter
142
+ def particle_ref(self):
143
+ self.particle_ref = None
144
+
145
+ @property
146
+ def capacity(self):
147
+ if self._capacity == 0:
148
+ return None
149
+ else:
150
+ return int(self._capacity)
151
+
152
+ @capacity.setter
153
+ def capacity(self, val):
154
+ if val is None:
155
+ val = 0
156
+ if not isinstance(val, Number) or val < 0:
157
+ raise ValueError("`capacity` has to be a positive integer!")
158
+ self._capacity = int(val)
159
+
160
+ @capacity.deleter
161
+ def capacity(self):
162
+ self.capacity = None
163
+
164
+ @property
165
+ def seed(self):
166
+ if self._seed == 0:
167
+ return None
168
+ else:
169
+ return self._seed
170
+
171
+ @seed.setter
172
+ def seed(self, val):
173
+ if val is None:
174
+ val = 0
175
+ if not isinstance(val, Number) or val < 0:
176
+ raise ValueError("`seed` has to be a positive integer!")
177
+ val = int(val)
178
+ if self._int32:
179
+ new_val = np.uint32(val)
180
+ else:
181
+ new_val = np.uint64(val)
182
+ if new_val != val:
183
+ self._print(f"Warning: type change for seed {val}. Using {new_val}.")
184
+ self._seed = new_val
185
+
186
+ @seed.deleter
187
+ def seed(self):
188
+ self.seed = None
189
+
190
+ @property
191
+ def input_file(self):
192
+ if self._uses_input_file:
193
+ return self._input_file
194
+
195
+ @property
196
+ def element_dict(self):
197
+ return self._element_dict
198
+
199
+
200
+ # ======================
201
+ # === Public Methods ===
202
+ # ======================
203
+
204
+ def start(self, *, clean=True, input_file=None, **kwargs):
205
+ if not self.environment:
206
+ raise RuntimeError(f"{self.name.capitalize()} environment not set up! "
207
+ + f"Do not manually create an instance of the engine.")
208
+ if not self.environment.initialised:
209
+ raise RuntimeError(f"{self.name.capitalize()} environment not initialised! "
210
+ + f"Please set all paths in the environment before "
211
+ + f"starting the engine.")
212
+ if not self.environment.compiled:
213
+ raise RuntimeError(f"{self.name.capitalize()} interface not compiled! "
214
+ + f"Please compile before starting the engine.")
215
+ if self.is_running():
216
+ self._print("Engine already running.")
217
+ return
218
+
219
+ # Clean up any leftover failed runs
220
+ self.stop(clean=clean)
221
+
222
+ print(f"Starting {self.__class__.__name__}... ", flush=True, end='')
223
+ kwargs = self._pre_start(**kwargs)
224
+
225
+ # This needs to be set in the ChildEngine, either in _start_engine() or at the start of tracking
226
+ self._tracking_initialised = False
227
+
228
+ # Set all engine properties that have a setter (this will remove these properties from the kwargs)
229
+ kwargs = self._set_engine_properties(**kwargs)
230
+
231
+ # Create input file if needed (this will remove the kwargs relevant to the input file and physics)
232
+ kwargs = self._use_input_file(input_file, **kwargs)
233
+ if clean:
234
+ self.clean_input_files(clean_all=False)
235
+ self._preparing_input = False
236
+
237
+ # Start the engine in the ChildEngine
238
+ self._start_engine(**kwargs)
239
+
240
+ # Done starting
241
+ if self.verbose:
242
+ print(f"{self.__class__.__name__} started.", flush=True)
243
+ else:
244
+ print(f"Done.", flush=True)
245
+
246
+ def stop(self, clean=False, **kwargs):
247
+ kwargs = self._stop_engine(**kwargs)
248
+ if clean:
249
+ self.clean(clean_all=True, **kwargs)
250
+ self._restore_engine_properties(clean=clean)
251
+ self._warning_given = False
252
+ self._tracking_initialised = False
253
+
254
+
255
+ def assert_particle_ref(self):
256
+ if self.particle_ref is None:
257
+ raise ValueError(f"{self.__class__.__name__} reference particle not set!")
258
+
259
+
260
+ def generate_input_file(self, *, clean=True, filename=None, **kwargs):
261
+ # This method manually generates an input file without starting the engine
262
+ if not self._uses_input_file:
263
+ raise ValueError(f"{self.__class__.__name__} does not use input files!")
264
+ if self._element_dict:
265
+ raise ValueError("Elements already assigned to engine (cannot regenerate input "
266
+ + "file after starting engine)!")
267
+
268
+ # Set all engine properties that have a setter (this will remove these properties from the kwargs)
269
+ kwargs = self._set_engine_properties(**kwargs)
270
+
271
+ # Create input file
272
+ input_file, _ = self._generate_input_file(**kwargs)
273
+ if not hasattr(input_file, '__iter__') or isinstance(input_file, str):
274
+ # Some engines might need multiple input files (like Fluka)
275
+ input_file = [input_file]
276
+ if filename is None:
277
+ if hasattr(self, '_old_cwd') and self._old_cwd is not None:
278
+ input_file[0] = input_file[0].rename(self._old_cwd / input_file[0].name)
279
+ else:
280
+ input_file[0] = input_file[0].rename(filename)
281
+ for i, file in enumerate(input_file[1:]):
282
+ input_file[i+1] = file.rename(input_file[0].parent / file.name)
283
+ input_file = input_file[0] if self._num_input_files==1 else input_file
284
+
285
+ if clean:
286
+ self.clean_input_files(clean_all=False)
287
+ self._restore_engine_properties(clean=clean)
288
+
289
+ return input_file
290
+
291
+
292
+ def is_running(self):
293
+ if hasattr(self, '_preparing_input') and self._preparing_input:
294
+ # We need this to allow changing the element settings which otherwise are locked
295
+ return False
296
+ # If we get here, we cannot say if the engine is running or not and we need an
297
+ # implementation in the child class
298
+ return self._is_running()
299
+
300
+
301
+ def clean(self, **kwargs):
302
+ self.clean_input_files(**kwargs)
303
+ self.clean_output_files(**kwargs)
304
+
305
+ def clean_input_files(self, **kwargs):
306
+ kwargs = self._get_input_cwd_for_cleaning(**kwargs)
307
+ self._clean_input_files(**kwargs)
308
+
309
+ def clean_output_files(self, **kwargs):
310
+ kwargs = self._get_input_cwd_for_cleaning(**kwargs)
311
+ self._clean_output_files(**kwargs)
312
+
313
+
314
+ # =======================
315
+ # === Private Methods ===
316
+ # =======================
317
+
318
+ # For all the engine fields, they can either be set in advance on the engine,
319
+ # or they can be set when the engine is started. In the latter case, the values
320
+ # are temporary and the original will be restored when the engine is stopped.
321
+
322
+ def _set_engine_properties(self, **kwargs):
323
+ self._preparing_input = True # We need this to allow changing the element settings which otherwise are locked
324
+ def _set_property(prop):
325
+ val = kwargs.pop(prop, None)
326
+ if val is not None:
327
+ # We only need to update the property when it is not None
328
+ setattr(self, f'_old_{prop}', getattr(self, prop))
329
+ setattr(self, prop, val)
330
+ # We need to set the following properties first as they are needed by the others
331
+ _set_property('verbose')
332
+ _set_property('line')
333
+ # The following properties have a specific logic
334
+ self._use_seed(kwargs.pop('seed', None))
335
+ self._use_particle_ref(kwargs.pop('particle_ref', None))
336
+ self._sync_line_particle_ref()
337
+ self._get_elements(kwargs.pop('elements', None), kwargs.pop('names', None))
338
+ self._set_cwd(kwargs.pop('cwd', None))
339
+ # Now we can set the rest of the properties
340
+ _set_property('capacity')
341
+ return kwargs
342
+
343
+ def _restore_engine_properties(self, clean=False):
344
+ self._preparing_input = False
345
+ # Reset particle_ref in the line
346
+ if hasattr(self, '_old_particle_ref'):
347
+ self.line.particle_ref = self._old_line_particle_ref
348
+ del self._old_line_particle_ref
349
+ # The following properties have a specific logic
350
+ self._reactivate_elements()
351
+ self._reset_cwd(clean=clean)
352
+ # Reset all other properties
353
+ self_attributes = self.__dict__.copy()
354
+ for kk, vv in self_attributes.items():
355
+ if kk.startswith('_old_'):
356
+ prop = kk[5:]
357
+ setattr(self, prop, vv)
358
+ delattr(self, kk)
359
+ self._input_file = None
360
+ self._element_dict = {}
361
+
362
+ def _use_seed(self, seed=None):
363
+ if seed is None:
364
+ if self.seed is None:
365
+ if self._int32:
366
+ self.seed = np.random.randint(0, int(2**32))
367
+ else:
368
+ self.seed = np.random.randint(0, int(2**64))
369
+ else:
370
+ self._old_seed = self.seed
371
+ self.seed = seed
372
+ self._print(f"Using seed {self.seed}.")
373
+
374
+ def _use_particle_ref(self, particle_ref=None):
375
+ # Prefer: provided particle_ref > existing particle_ref > particle_ref from line
376
+ if particle_ref is not None:
377
+ self._old_particle_ref = self.particle_ref
378
+ self.particle_ref = particle_ref
379
+ elif self.particle_ref is None:
380
+ if self.line is None or not hasattr(self.line, 'particle_ref') \
381
+ or self.line.particle_ref is None:
382
+ raise ValueError("Need to provide either a line with a reference "
383
+ + "particle, or `particle_ref`.")
384
+ self._old_particle_ref = self.particle_ref
385
+ self.particle_ref = self.line.particle_ref
386
+ self._print(f"Using {pdg.get_name_from_pdg_id(self.particle_ref.pdg_id[0])} "
387
+ + f"with momentum {self.particle_ref.p0c[0]/1.e9:.1f} GeV.")
388
+
389
+ def _sync_line_particle_ref(self):
390
+ if self.line is None:
391
+ return
392
+ if self.line.particle_ref is not None \
393
+ and not xt.line._dicts_equal(self.line.particle_ref.to_dict(),
394
+ self.particle_ref.to_dict()):
395
+ self._print("Found different reference particle in line. Temporarily overwritten.")
396
+ self._old_line_particle_ref = self.line.particle_ref
397
+ self.line.particle_ref = self.particle_ref
398
+
399
+ def _get_new_element_name(self):
400
+ name = f"{self.name}_el_{self._element_index}"
401
+ self._element_index += 1
402
+ return name
403
+
404
+ def _deactivate_element(self, el):
405
+ self._deactivated_elements[el.name] = [el, el.active or True]
406
+ if hasattr(el, 'active'):
407
+ el.active = False
408
+ self._remove_element(el)
409
+
410
+ def _assert_element(self, element):
411
+ if not isinstance(element, self._element_classes):
412
+ raise ValueError(f"Element {element.name} is not a "
413
+ + ", or a ".join([c.__name__ for c in self._element_classes])
414
+ + ".")
415
+
416
+ def _get_elements(self, elements=None, names=None):
417
+ if elements is not None and (not hasattr(elements, '__iter__') or isinstance(elements, str)):
418
+ elements = [elements]
419
+ if names is not None and (not hasattr(names, '__iter__') or isinstance(names, str)):
420
+ names = [names]
421
+ if self.line is None:
422
+ if elements is None:
423
+ raise ValueError("Need to provide either `line` or `elements`.")
424
+ if names is None:
425
+ names = []
426
+ for ee in elements:
427
+ if hasattr(ee, 'name'):
428
+ names.append(ee.name)
429
+ else:
430
+ name = self._get_new_element_name()
431
+ names.append(name)
432
+ ee.name = name
433
+ elif len(names) == len(elements):
434
+ for ee, name in zip(elements, names):
435
+ if hasattr(ee, 'name'):
436
+ if ee.name != name:
437
+ self._print(f"Warning: Element name {ee.name} changed to {name}.")
438
+ ee.name = name
439
+ else:
440
+ raise ValueError("Length of `elements` and `names` doesn't match.")
441
+ else:
442
+ if elements is not None:
443
+ raise ValueError("Cannot provide both `line` and `elements`.")
444
+ if names is None:
445
+ elements, names = self.line.get_elements_of_type(self._element_classes)
446
+ else:
447
+ elements = [self.line[name] for name in names]
448
+ this_names = []
449
+ this_elements = []
450
+ for ee, name in zip(elements, names):
451
+ self._assert_element(ee)
452
+ if ee.jaw is None:
453
+ self._print(f"Warning: Jaw not set for {name}. Ignoring.")
454
+ self._deactivate_element(ee)
455
+ elif not ee.active:
456
+ self._print(f"Warning: Element {name} is not active. Ignoring.")
457
+ self._deactivate_element(ee)
458
+ else:
459
+ this_names.append(name)
460
+ this_elements.append(ee)
461
+ if len(this_elements) == 0:
462
+ raise ValueError(f"No active {self.name} elements found!")
463
+ self._element_dict = dict(zip(this_names, this_elements))
464
+
465
+ def _reactivate_elements(self):
466
+ names = list(self._deactivated_elements.keys())
467
+ for name in names:
468
+ ee, was_active = self._deactivated_elements.pop(name)
469
+ self._restore_element(ee)
470
+ if hasattr(ee, 'active'):
471
+ ee.active = was_active
472
+
473
+ def _set_cwd(self, cwd=None):
474
+ if self._uses_run_folder:
475
+ if cwd is not None:
476
+ cwd = FsPath(cwd).expanduser().resolve()
477
+ if cwd.exists() and cwd != FsPath.cwd():
478
+ # Check if the folder already exists
479
+ # If the specified folder is the current one, we do not need to rename
480
+ i = 0
481
+ while (cwd.parent / f'{cwd.name}_{i:0>4}').exists():
482
+ i += 1
483
+ if i > 9999:
484
+ raise ValueError(f"Too many folders with the same "
485
+ + f"name {cwd}!")
486
+ cwd = cwd.parent / f'{cwd.name}_{i:0>4}'
487
+ else:
488
+ ran_str = ranID(only_alphanumeric=True)
489
+ cwd = FsPath.cwd() / f'{self.name}_run_{ran_str}'
490
+ self._cwd = cwd
491
+ cwd.mkdir(parents=True, exist_ok=True)
492
+ self._old_cwd = FsPath.cwd()
493
+ os.chdir(cwd)
494
+
495
+ def _reset_cwd(self, clean=False):
496
+ if hasattr(self, '_old_cwd'):
497
+ if self._old_cwd is not None:
498
+ os.chdir(self._old_cwd)
499
+ if clean and self._cwd is not None and self._cwd != FsPath.cwd():
500
+ try:
501
+ self._cwd.rmdir()
502
+ except:
503
+ self._print(f"Warning: Failed to remove temporary folder "
504
+ + f"{self._cwd}.")
505
+ del self._old_cwd
506
+ self._cwd = None
507
+
508
+
509
+ def _use_input_file(self, input_file=None, **kwargs):
510
+ if self._uses_input_file:
511
+ if input_file is None:
512
+ input_file, kwargs = self._generate_input_file(**kwargs)
513
+ if not hasattr(input_file, '__iter__') or isinstance(input_file, str):
514
+ # Some engines might need multiple input files (like Fluka)
515
+ input_file = [input_file]
516
+ input_file = [FsPath(f).expanduser().resolve() for f in input_file]
517
+ new_files = []
518
+ for file in input_file:
519
+ if not file.exists():
520
+ raise ValueError(f"Input file {file.as_posix()} not found!")
521
+ if file.parent != FsPath.cwd() and self._uses_run_folder:
522
+ file.copy_to(FsPath.cwd(), method='mount')
523
+ new_files.append(FsPath.cwd() / file.name)
524
+ else:
525
+ new_files.append(file)
526
+ self._input_file = new_files[0] if self._num_input_files==1 else new_files
527
+ self._match_input_file()
528
+ return kwargs
529
+
530
+
531
+ def _get_input_cwd_for_cleaning(self, **kwargs):
532
+ # Get the input file and the cwd
533
+ input_file = kwargs.get('input_file', None)
534
+ cwd = kwargs.get('cwd', None)
535
+ if input_file is None:
536
+ if self.input_file is not None:
537
+ input_file = self.input_file
538
+ if cwd is None and self._cwd is not None:
539
+ cwd = self._cwd
540
+ else:
541
+ if not hasattr(input_file, '__iter__') or isinstance(input_file, str):
542
+ input_file = [input_file]
543
+ input_file = [FsPath(ff) for ff in input_file]
544
+ if cwd is None:
545
+ cwd = input_file[0].parent
546
+ if len(input_file) == 1:
547
+ input_file = input_file[0]
548
+ kwargs['input_file'] = input_file
549
+ if self._uses_run_folder:
550
+ kwargs['cwd'] = cwd
551
+ else:
552
+ kwargs['cwd'] = FsPath.cwd()
553
+ return kwargs
554
+
555
+
556
+ # =================================================
557
+ # === Methods to be overwritten by child engine ===
558
+ # =================================================
559
+
560
+ def _start_engine(self, **kwargs):
561
+ raise NotImplementedError(f"Need to implement `_start_engine` for "
562
+ + f"{self.__class__.__name__}!")
563
+
564
+ def _stop_engine(self, **kwargs):
565
+ raise NotImplementedError(f"Need to implement `_stop_engine` for "
566
+ + f"{self.__class__.__name__}!")
567
+
568
+ def _is_running(self, **kwargs):
569
+ raise NotImplementedError(f"Need to implement `_is_running` for "
570
+ + f"{self.__class__.__name__}!")
571
+
572
+ def _match_input_file(self, **kwargs):
573
+ if self._uses_input_file:
574
+ raise NotImplementedError(f"Need to implement `_match_input_file` for "
575
+ + f"{self.__class__.__name__}!")
576
+
577
+ def _generate_input_file(self, **kwargs):
578
+ if self._uses_input_file:
579
+ raise NotImplementedError("Need to implement `_generate_input_file` for "
580
+ + f"{self.__class__.__name__}!")
581
+
582
+
583
+ # ============================================================
584
+ # === Methods to be optionally overwritten by child engine ===
585
+ # ============================================================
586
+
587
+ def _clean_input_files(self, input_file=None, cwd=None, clean_all=False, **kwargs):
588
+ pass
589
+
590
+ def _clean_output_files(self, input_file=None, cwd=None, clean_all=False, **kwargs):
591
+ pass
592
+
593
+ def _remove_element(self, el):
594
+ pass
595
+
596
+ def _restore_element(self, el):
597
+ pass
598
+
599
+ def _pre_start(self, **kwargs):
600
+ return kwargs