hutch-python 1.21.0__tar.gz → 1.23.0__tar.gz

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.
Files changed (149) hide show
  1. {hutch_python-1.21.0 → hutch_python-1.23.0}/.github/workflows/standard.yml +2 -2
  2. {hutch_python-1.21.0 → hutch_python-1.23.0}/.pre-commit-config.yaml +3 -3
  3. {hutch_python-1.21.0 → hutch_python-1.23.0}/PKG-INFO +6 -6
  4. {hutch_python-1.21.0 → hutch_python-1.23.0}/conda-recipe/meta.yaml +3 -3
  5. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/releases.rst +63 -0
  6. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/yaml_files.rst +60 -3
  7. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs-requirements.txt +0 -2
  8. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/_version.py +9 -4
  9. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/calc_defaults.py +10 -0
  10. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/constants.py +2 -0
  11. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/happi.py +85 -32
  12. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/ipython_session_timer.py +2 -2
  13. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/load_conf.py +34 -4
  14. hutch_python-1.23.0/hutch_python/startup_script.py +49 -0
  15. hutch_python-1.23.0/hutch_python/tests/conf.yaml +15 -0
  16. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/test_cli.py +5 -2
  17. hutch_python-1.23.0/hutch_python/tests/test_happi.py +147 -0
  18. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python.egg-info/PKG-INFO +6 -6
  19. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python.egg-info/requires.txt +3 -4
  20. {hutch_python-1.21.0 → hutch_python-1.23.0}/requirements.txt +3 -3
  21. hutch_python-1.21.0/hutch_python/startup_script.py +0 -32
  22. hutch_python-1.21.0/hutch_python/tests/conf.yaml +0 -7
  23. hutch_python-1.21.0/hutch_python/tests/test_happi.py +0 -65
  24. {hutch_python-1.21.0 → hutch_python-1.23.0}/.coveragerc +0 -0
  25. {hutch_python-1.21.0 → hutch_python-1.23.0}/.flake8 +0 -0
  26. {hutch_python-1.21.0 → hutch_python-1.23.0}/.git_archival.txt +0 -0
  27. {hutch_python-1.21.0 → hutch_python-1.23.0}/.gitattributes +0 -0
  28. {hutch_python-1.21.0 → hutch_python-1.23.0}/.github/ISSUE_TEMPLATE.md +0 -0
  29. {hutch_python-1.21.0 → hutch_python-1.23.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  30. {hutch_python-1.21.0 → hutch_python-1.23.0}/.gitignore +0 -0
  31. {hutch_python-1.21.0 → hutch_python-1.23.0}/.landscape.yml +0 -0
  32. {hutch_python-1.21.0 → hutch_python-1.23.0}/AUTHORS.rst +0 -0
  33. {hutch_python-1.21.0 → hutch_python-1.23.0}/CONTRIBUTING.rst +0 -0
  34. {hutch_python-1.21.0 → hutch_python-1.23.0}/LICENSE +0 -0
  35. {hutch_python-1.21.0 → hutch_python-1.23.0}/MANIFEST.in +0 -0
  36. {hutch_python-1.21.0 → hutch_python-1.23.0}/README.rst +0 -0
  37. {hutch_python-1.21.0 → hutch_python-1.23.0}/bin/hutch-python +0 -0
  38. {hutch_python-1.21.0 → hutch_python-1.23.0}/dev-requirements.txt +0 -0
  39. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/Makefile +0 -0
  40. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/hutch_python.ipynb +0 -0
  41. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/pre-release-notes.sh +0 -0
  42. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/release_notes.py +0 -0
  43. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/beamline.rst +0 -0
  44. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/bug.rst +0 -0
  45. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/cache.rst +0 -0
  46. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/cli.rst +0 -0
  47. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/conf.py +0 -0
  48. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/daq.rst +0 -0
  49. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/database.rst +0 -0
  50. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/debug.rst +0 -0
  51. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/environment.rst +0 -0
  52. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/experiment.rst +0 -0
  53. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/hutch_setup.rst +0 -0
  54. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/index.rst +0 -0
  55. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/ipython_log.rst +0 -0
  56. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/load_conf.rst +0 -0
  57. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/load_parts.rst +0 -0
  58. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/log_setup.rst +0 -0
  59. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/namespace.rst +0 -0
  60. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/object_configuration.rst +0 -0
  61. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/other_modules.rst +0 -0
  62. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/presets.rst +0 -0
  63. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/report.rst +0 -0
  64. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/start.rst +0 -0
  65. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/startup.rst +0 -0
  66. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/tips.rst +0 -0
  67. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/tutorial.ipynb +0 -0
  68. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/upcoming_release_notes/template-full.rst +0 -0
  69. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/upcoming_release_notes/template-short.rst +0 -0
  70. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/user_utils.rst +0 -0
  71. {hutch_python-1.21.0 → hutch_python-1.23.0}/docs/source/utils.rst +0 -0
  72. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/__init__.py +0 -0
  73. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/__main__.py +0 -0
  74. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/bug.py +0 -0
  75. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/cache.py +0 -0
  76. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/cam_load.py +0 -0
  77. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/cli.py +0 -0
  78. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/cookiecutter/cookiecutter.json +0 -0
  79. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/.gitignore +0 -0
  80. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/README.md +0 -0
  81. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/conf.yml +0 -0
  82. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/experiments/__init__.py +0 -0
  83. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/set-dev +0 -0
  84. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/{{ cookiecutter.hutch }}/__init__.py +0 -0
  85. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/{{ cookiecutter.hutch }}/beamline.py +0 -0
  86. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/{{ cookiecutter.hutch }}env +0 -0
  87. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/{{ cookiecutter.hutch }}python +0 -0
  88. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/debug.py +0 -0
  89. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/env_version.py +0 -0
  90. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/epics_arch.py +0 -0
  91. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/exp_load.py +0 -0
  92. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/ipython_log.py +0 -0
  93. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/lcls.py +0 -0
  94. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/log_setup.py +0 -0
  95. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/logging.yml +0 -0
  96. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/mpl_config.py +0 -0
  97. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/namespace.py +0 -0
  98. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/obj_config.py +0 -0
  99. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/ophyd_settings.py +0 -0
  100. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/options.py +0 -0
  101. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/plan_defaults.py +0 -0
  102. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/plan_wrappers.py +0 -0
  103. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/print_hint_banner.py +0 -0
  104. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/pt_app_config.py +0 -0
  105. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/qs_load.py +0 -0
  106. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/sim.py +0 -0
  107. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/templates/issue.template +0 -0
  108. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/__init__.py +0 -0
  109. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/bad_script.py +0 -0
  110. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/camviewer.cfg +0 -0
  111. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/conftest.py +0 -0
  112. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/envs/pcds-1.0.0 +0 -0
  113. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/envs/pcds-2.0.0 +0 -0
  114. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/envs/z-env +0 -0
  115. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/experiments/sample_expname.py +0 -0
  116. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/experiments/x010.py +0 -0
  117. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/experiments/x011.py +0 -0
  118. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/happi_db.json +0 -0
  119. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/sample_module_1.py +0 -0
  120. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/sample_module_2.py +0 -0
  121. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/script.py +0 -0
  122. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/test_bug.py +0 -0
  123. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/test_cache.py +0 -0
  124. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/test_cam_load.py +0 -0
  125. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/test_epics_arch.py +0 -0
  126. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/test_experiment.py +0 -0
  127. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/test_ipython_log.py +0 -0
  128. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/test_ipython_session_timer.py +0 -0
  129. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/test_load_conf.py +0 -0
  130. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/test_log_setup.py +0 -0
  131. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/test_namespace.py +0 -0
  132. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/test_obj_config.py +0 -0
  133. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/test_plan_wrappers.py +0 -0
  134. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/test_questionnaire.py +0 -0
  135. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/test_tstpython.py +0 -0
  136. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/test_user_load.py +0 -0
  137. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/test_utils.py +0 -0
  138. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/tst/__init__.py +0 -0
  139. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/tst/beamline.py +0 -0
  140. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/tests/tstpython +0 -0
  141. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/user_load.py +0 -0
  142. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/utils.py +0 -0
  143. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python/version.py +0 -0
  144. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python.egg-info/SOURCES.txt +0 -0
  145. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python.egg-info/dependency_links.txt +0 -0
  146. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python.egg-info/entry_points.txt +0 -0
  147. {hutch_python-1.21.0 → hutch_python-1.23.0}/hutch_python.egg-info/top_level.txt +0 -0
  148. {hutch_python-1.21.0 → hutch_python-1.23.0}/pyproject.toml +0 -0
  149. {hutch_python-1.21.0 → hutch_python-1.23.0}/setup.cfg +0 -0
@@ -18,10 +18,10 @@ jobs:
18
18
  # Extras that will be installed for both conda/pip:
19
19
  testing-extras: ""
20
20
  # Extras to be installed only for conda-based testing:
21
- conda-testing-extras: "ipython=8.4.0"
21
+ conda-testing-extras: ""
22
22
  # Extras to be installed only for pip-based testing:
23
23
  # Set numpy<2 for now, remove when xraylib updates
24
- pip-testing-extras: "ipython==8.4.0 numpy<2"
24
+ pip-testing-extras: ""
25
25
  # System packages to be installed only for conda-based testing:
26
26
  conda-system-packages: ""
27
27
  # System packages to be installed only for pip-based testing:
@@ -7,7 +7,7 @@ exclude: |
7
7
 
8
8
  repos:
9
9
  - repo: https://github.com/pre-commit/pre-commit-hooks
10
- rev: v4.4.0
10
+ rev: v5.0.0
11
11
  hooks:
12
12
  - id: no-commit-to-branch
13
13
  - id: trailing-whitespace
@@ -27,11 +27,11 @@ repos:
27
27
  - id: debug-statements
28
28
 
29
29
  - repo: https://github.com/pycqa/flake8.git
30
- rev: 6.0.0
30
+ rev: 7.2.0
31
31
  hooks:
32
32
  - id: flake8
33
33
 
34
34
  - repo: https://github.com/timothycrosley/isort
35
- rev: 5.12.0
35
+ rev: 6.0.1
36
36
  hooks:
37
37
  - id: isort
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: hutch-python
3
- Version: 1.21.0
3
+ Version: 1.23.0
4
4
  Summary: Launcher and Config Reader for LCLS Interactive IPython Sessions
5
5
  Author: SLAC National Accelerator Laboratory
6
6
  License: Copyright (c) 2023, The Board of Trustees of the Leland Stanford Junior
@@ -55,14 +55,14 @@ Requires-Dist: bluesky>=1.8.0
55
55
  Requires-Dist: coloredlogs>=15.0.0
56
56
  Requires-Dist: cookiecutter>=1.7.0
57
57
  Requires-Dist: happi>=1.9.0
58
- Requires-Dist: ipython>=7.26.0
58
+ Requires-Dist: ipython<9.0.0
59
59
  Requires-Dist: jinja2>=2.11.0
60
60
  Requires-Dist: lightpath>=1.0.1
61
61
  Requires-Dist: matplotlib>=3.4.0
62
62
  Requires-Dist: nabs>=1.5.0
63
- Requires-Dist: pcdscalc>=0.3.0
63
+ Requires-Dist: pcdscalc>=0.6.0
64
64
  Requires-Dist: pcdsdaq>=2.3.0
65
- Requires-Dist: pcdsdevices>=7.0.0
65
+ Requires-Dist: pcdsdevices>8.7.0
66
66
  Requires-Dist: pcdsutils>=0.5.0
67
67
  Requires-Dist: psdaq-control-minimal
68
68
  Requires-Dist: pyfiglet>=0.8.0
@@ -83,7 +83,7 @@ Requires-Dist: sphinx; extra == "doc"
83
83
  Requires-Dist: sphinx_rtd_theme; extra == "doc"
84
84
  Requires-Dist: sphinxcontrib-jquery; extra == "doc"
85
85
  Requires-Dist: pypandoc; extra == "doc"
86
- Requires-Dist: numpy<2; extra == "doc"
86
+ Dynamic: license-file
87
87
 
88
88
  ============
89
89
  Hutch Python
@@ -27,14 +27,14 @@ requirements:
27
27
  - cookiecutter >=1.7.0
28
28
  - elog >=1.1.0
29
29
  - happi >=1.9.0
30
- - ipython >=7.26.0
30
+ - ipython <9.0.0
31
31
  - jinja2 >=2.11.0
32
32
  - lightpath >=1.0.1
33
33
  - matplotlib-base >=3.4.0
34
34
  - nabs >=1.5.0
35
- - pcdscalc >=0.3.0
35
+ - pcdscalc >=0.6.0
36
36
  - pcdsdaq >=2.3.0
37
- - pcdsdevices >=7.0.0
37
+ - pcdsdevices >8.7.0
38
38
  - pcdsutils >=0.6.0
39
39
  - psdaq-control-minimal >=3.3.19
40
40
  - psdm_qs_cli >=0.3.1
@@ -2,6 +2,69 @@ Release History
2
2
  ###############
3
3
 
4
4
 
5
+ v1.23.0 (2025-04-07)
6
+ ====================
7
+
8
+ Features
9
+ --------
10
+ - Added ability to load additional devices not on the current beamline or hutch/area using happi search.
11
+
12
+ Bugfixes
13
+ --------
14
+ - update functions anticipating py3.12 and IPython > 8.26
15
+
16
+ Maintenance
17
+ -----------
18
+ - Enable the deferral of preset loading to avoid a pre-mature performance hit
19
+
20
+ Contributors
21
+ ------------
22
+ - janeliu-slac
23
+ - tangkong
24
+
25
+
26
+
27
+ v1.22.0 (2024-12-19)
28
+ ====================
29
+
30
+ Features
31
+ --------
32
+ - Add ``pcdscalc.xray`` to the calc namespace.
33
+ - Add top-level shortcuts to some of the most used calcs,
34
+ ``E2lam``, ``lam2E``, ``bragg_angle``, ``darwin_width``,
35
+ and ``transmission``.
36
+ ``E2lam`` is an alias for ``energy_to_wavelength`` and
37
+ ``lam2E`` is an alias for ``wavelength_to_energy``
38
+ to match scientist expectations.
39
+ - Added ability to ignore specific upstream devices when loading hutch-python.
40
+
41
+ - ``UPSTREAM``: The hutch's devices, and devices upstream from the requested hutch.
42
+ If there are multiple paths to the requested hutch, all paths devices are loaded.
43
+ - ``STANDARD``: Devices gathered via ``UPSTREAM``, plus devices that share the
44
+ "beamline" field in happi with the ``UPSTREAM`` devices. (The current standard)
45
+ - ``ALL``: All devices in the happi database. Use this option at your own risk.
46
+
47
+
48
+ Bugfixes
49
+ --------
50
+ - Make test_create_arg agnostic to where pytest was invoked from
51
+ - Fix an issue where the user could clobber their own ``elog``
52
+ object in a way that would allow the ``ElogPoster`` utility to
53
+ load and then fail at scan time.
54
+
55
+ Maintenance
56
+ -----------
57
+ - Updates documentation formatting for device load_level, and adds an ascii beamline map to the test suite
58
+
59
+ Contributors
60
+ ------------
61
+ - janeliu-slac
62
+ - tangkong
63
+ - vespos
64
+ - zllentz
65
+
66
+
67
+
5
68
  v1.21.0 (2024-08-20)
6
69
  ====================
7
70
 
@@ -4,7 +4,7 @@ Yaml Files
4
4
  ``hutch-python`` uses a ``conf.yml`` file for basic configuration. This is a
5
5
  standard yaml file with the following valid keys:
6
6
  ``hutch``, ``db``, ``load``, ``load_level``, ``experiment``, ``obj_config``,
7
- ``daq_type``, ``daq_host``, and ``daq_platform``.
7
+ ``daq_type``, ``daq_host``, and ``daq_platform``, ``exclude_devices``.
8
8
 
9
9
 
10
10
  hutch
@@ -75,9 +75,11 @@ The ``load_level`` key expects one of the following strings, corresponding to th
75
75
  amount of ophyd devices to load:
76
76
 
77
77
  - ``UPSTREAM``: The hutch's devices, and devices upstream from the requested hutch.
78
- If there are multiple paths to the requested hutch, all paths' devices are loaded.
78
+ If there are multiple paths to the requested hutch, all paths' devices are loaded.
79
+
79
80
  - ``STANDARD``: Devices gathered via ``UPSTREAM``, plus devices that share the
80
- "beamline" field in happi with the ``UPSTREAM`` devices. (The current standard)
81
+ "beamline" field in happi with the ``UPSTREAM`` devices. (The current standard)
82
+
81
83
  - ``ALL``: All devices in the happi database. Use this option at your own risk.
82
84
 
83
85
  .. code-block:: YAML
@@ -104,6 +106,7 @@ particular experiment.
104
106
 
105
107
  .. _obj_conf_yaml:
106
108
 
109
+
107
110
  obj_conf
108
111
  --------
109
112
 
@@ -135,6 +138,7 @@ This key expects a string with one of four valid values:
135
138
  LCLS1-style daq, a simulated LCLS1-style daq, an LCLS2-style daq,
136
139
  or no daq respectively.
137
140
 
141
+
138
142
  daq_host
139
143
  --------
140
144
 
@@ -142,6 +146,7 @@ The daq collection host as a string. This is a required key
142
146
  when using the lcls2 daq_type, and is ignored with any other daq_type.
143
147
  It will be used in the creation of the lcls2 daq object.
144
148
 
149
+
145
150
  daq_platform
146
151
  ------------
147
152
 
@@ -155,6 +160,58 @@ experiment. Additional keys are interpreted as hostnames to use
155
160
  alternate platforms for. Alternate platforms will post to the
156
161
  secondary elog.
157
162
 
163
+
164
+ exclude_devices
165
+ ------------
166
+ The ``exclude_devices`` key is optional. ``exclude_devices`` expects a string
167
+ that starts with a "-" symbol on each line. The string is the name of a device
168
+ that should not be loaded.
169
+
170
+ This feature reduces the amount of unnecessary information shown in the console
171
+ at load time. The list uses the following format:
172
+
173
+ .. code-block:: YAML
174
+
175
+ exclude_devices:
176
+ - crix_cryo_y
177
+ - at2k2_calc
178
+ - tmo_lamp_sqr1
179
+
180
+
181
+ additional_devices
182
+ ------------
183
+ The ``additional_devices`` key is optional. This key allows hutch-python to
184
+ load additional devices that are on a different beamline or in a different
185
+ hutch/area. The first entry below ``additional_devices`` is a search name,
186
+ such as 'tmo_sqr1_search'. Search names are arbitrarily determined by the user
187
+ but should start with a letter or number. Each search name is followed by a
188
+ happi search key, such as "beamline" and a value. For example, "beamline: TMO".
189
+ This tells hutch-python to gather all devices on the TMO beamline and load
190
+ them. A second search criterion can be added below "beamline: TMO" to constrain
191
+ the search further, so that only those devices that fit both search criteria
192
+ will be loaded. For example, adding "device_class: pcdsdevices.sqr1.SQR1" below
193
+ "beamline: TMO" tells hutch-python to load devices from the TMO beamline whose
194
+ "device_class" key has a value of "pcdsdevices.sqr1.SQR1". More lines can be
195
+ added to obtain even more specific search results.
196
+
197
+ A search value can contain a wildcard symbol (*). For example, "name: tmo_*".
198
+
199
+ In the example below hutch-python will load all devices from "tmo_sqr1_search",
200
+ "las_search", and "crix_search".
201
+
202
+ .. code-block:: YAML
203
+
204
+ additional_devices:
205
+ tmo_sqr1_search:
206
+ beamline: TMO
207
+ device_class: pcdsdevices.sqr1.SQR1
208
+ z: -1, 1
209
+ las_search:
210
+ name: LAS
211
+ crix_search:
212
+ name: crix_*
213
+
214
+
158
215
  Full File Example
159
216
  -----------------
160
217
 
@@ -4,5 +4,3 @@ sphinx
4
4
  sphinx_rtd_theme
5
5
  sphinxcontrib-jquery
6
6
  pypandoc
7
- # Temporary pin, xraylib 4.1.3 (pcdscalc) incompatible
8
- numpy <2
@@ -1,8 +1,13 @@
1
- # file generated by setuptools_scm
1
+ # file generated by setuptools-scm
2
2
  # don't change, don't track in version control
3
+
4
+ __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
5
+
3
6
  TYPE_CHECKING = False
4
7
  if TYPE_CHECKING:
5
- from typing import Tuple, Union
8
+ from typing import Tuple
9
+ from typing import Union
10
+
6
11
  VERSION_TUPLE = Tuple[Union[int, str], ...]
7
12
  else:
8
13
  VERSION_TUPLE = object
@@ -12,5 +17,5 @@ __version__: str
12
17
  __version_tuple__: VERSION_TUPLE
13
18
  version_tuple: VERSION_TUPLE
14
19
 
15
- __version__ = version = '1.21.0'
16
- __version_tuple__ = version_tuple = (1, 21, 0)
20
+ __version__ = version = '1.23.0'
21
+ __version_tuple__ = version_tuple = (1, 23, 0)
@@ -1,5 +1,9 @@
1
1
  from importlib import import_module
2
2
 
3
+ from pcdscalc.common import energy_to_wavelength, wavelength_to_energy
4
+ from pcdscalc.diffraction import bragg_angle, darwin_width
5
+ from pcdscalc.xray import transmission
6
+
3
7
  from .utils import HelpfulNamespace
4
8
 
5
9
 
@@ -33,7 +37,13 @@ def collect_functions(modules):
33
37
 
34
38
 
35
39
  calc_namespace = HelpfulNamespace(
40
+ E2lam=energy_to_wavelength,
41
+ lam2E=wavelength_to_energy,
42
+ bragg_angle=bragg_angle,
43
+ darwin_width=darwin_width,
44
+ transmission=transmission,
36
45
  be_lens=collect_functions(['pcdscalc.be_lens_calcs']),
37
46
  common=collect_functions(['pcdscalc.common']),
38
47
  diffraction=collect_functions(['pcdscalc.diffraction']),
48
+ xray=collect_functions(['pcdscalc.xray']),
39
49
  )
@@ -39,6 +39,8 @@ VALID_KEYS = (
39
39
  'daq_host',
40
40
  'obj_config',
41
41
  'session_timer',
42
+ 'exclude_devices',
43
+ 'additional_devices'
42
44
  )
43
45
  NO_LOG_EXCEPTIONS = (KeyboardInterrupt, SystemExit)
44
46
  LOG_DOMAINS = {".pcdsn", ".slac.stanford.edu"}
@@ -1,9 +1,11 @@
1
1
  import enum
2
2
  import inspect
3
3
  import logging
4
+ from typing import Dict, List, Optional
4
5
 
5
6
  import happi
6
7
  import ophyd
8
+ from happi.cli import search_parser
7
9
  from happi.loader import load_devices
8
10
 
9
11
  try:
@@ -29,7 +31,9 @@ def get_happi_objs(
29
31
  db: str,
30
32
  light_ctrl: LightController,
31
33
  endstation: str,
32
- load_level: DeviceLoadLevel = DeviceLoadLevel.STANDARD
34
+ load_level: DeviceLoadLevel = DeviceLoadLevel.STANDARD,
35
+ exclude_devices: Optional[List[str]] = None,
36
+ additional_devices: Optional[Dict[str, Dict[str, str]]] = None
33
37
  ) -> dict[str, ophyd.Device]:
34
38
  """
35
39
  Get the relevant items for ``endstation`` from the happi database ``db``.
@@ -52,11 +56,30 @@ def get_happi_objs(
52
56
  endstation: ``str``
53
57
  Name of hutch
54
58
 
59
+ load_level: ``DeviceLoadLevel``
60
+ load all or standard devices
61
+
62
+ exclude_devices: ``Optional[List[str]]``
63
+ an optional list of devices that should be excluded when loading
64
+
65
+ additional_devices: ``Optional[Dict[str, Dict[str, str]]]``
66
+ an optional dictionary of dictionaries with happi search terms
67
+ whose results are loaded
68
+
55
69
  Returns
56
70
  -------
57
71
  objs: ``dict``
58
72
  A mapping from item name to item
59
73
  """
74
+
75
+ # Explicitly set exclude_devices and additional_devices to empty
76
+ # containers to avoid mutable default arguments issue.
77
+ if not exclude_devices:
78
+ exclude_devices = []
79
+
80
+ if not additional_devices:
81
+ additional_devices = {}
82
+
60
83
  # Load the happi Client
61
84
  if None not in (light_ctrl, lightpath):
62
85
  client = light_ctrl.client
@@ -67,47 +90,73 @@ def get_happi_objs(
67
90
  if load_level == DeviceLoadLevel.ALL:
68
91
  results = client.search(active=True)
69
92
  containers.extend(res.item for res in results)
70
- return _load_devices(*containers)
71
93
 
72
- if light_ctrl is None or (endstation.upper() not in light_ctrl.beamlines):
94
+ elif light_ctrl is None or (endstation.upper() not in light_ctrl.beamlines):
73
95
  # lightpath was unavailable, search by beamline name
74
96
  reqs = dict(beamline=endstation.upper(), active=True)
75
97
  results = client.search(**reqs)
76
98
  containers.extend(res.item for res in results)
77
- return _load_devices(*containers)
78
-
79
- # if lightpath exists, we can grab upstream devices
80
- dev_names = set()
81
- paths = light_ctrl.beamlines[endstation.upper()]
82
- for path in paths:
83
- dev_names.update(path)
84
99
 
85
- # gather happi items for each of these
86
- for name in dev_names:
87
- results = client.search(name=name)
88
- containers.extend(res.item for res in results)
89
-
90
- if load_level >= DeviceLoadLevel.STANDARD:
91
- # also any device with the same beamline name
92
- # since lightpath only grabs lightpath-active devices
93
- beamlines = {it.beamline for it in containers}
94
- beamlines.add(endstation.upper())
95
-
96
- for line in beamlines:
97
- # Assume we want hutch items that are active
98
- # items can be lightpath-inactive
99
- reqs = dict(beamline=line, active=True)
100
- results = client.search(**reqs)
101
- blc = [res.item for res in results
102
- if res.item.name not in dev_names]
103
- # Add the beamline containers to the complete list
104
- if blc:
105
- containers.extend(blc)
100
+ else:
101
+ # if lightpath exists, we can grab upstream devices
102
+ dev_names = set()
103
+ paths = light_ctrl.beamlines[endstation.upper()]
104
+ for path in paths:
105
+ dev_names.update(path)
106
+
107
+ # gather happi items for each of these
108
+ for name in dev_names:
109
+ results = client.search(name=name)
110
+ containers.extend(res.item for res in results)
111
+
112
+ if load_level >= DeviceLoadLevel.STANDARD:
113
+ # also any device with the same beamline name
114
+ # since lightpath only grabs lightpath-active devices
115
+ beamlines = {it.beamline for it in containers}
116
+ beamlines.add(endstation.upper())
117
+
118
+ for line in beamlines:
119
+ # Assume we want hutch items that are active
120
+ # items can be lightpath-inactive
121
+ reqs = dict(beamline=line, active=True)
122
+ results = client.search(**reqs)
123
+ blc = [res.item for res in results
124
+ if res.item.name not in dev_names]
125
+ # Add the beamline containers to the complete list
126
+ if blc:
127
+ containers.extend(blc)
106
128
 
107
129
  if len(containers) < 1:
108
130
  logger.warning(f'{len(containers)} active devices found for '
109
131
  'this beampath')
110
132
 
133
+ # Load additional devices
134
+ for search_val in additional_devices.values():
135
+
136
+ search_list = []
137
+ final_results = []
138
+
139
+ for entry_key, entry_val in search_val.items():
140
+ search_string = entry_key + '=' + entry_val
141
+ search_list.append(search_string)
142
+
143
+ search_results = search_parser(
144
+ client=client,
145
+ use_glob=True,
146
+ search_criteria=search_list
147
+ )
148
+ search_results = list(search_results)
149
+ final_results += search_results
150
+ final_results = list(set(final_results))
151
+
152
+ containers.extend(
153
+ res.item for res in final_results if res.item not in containers)
154
+
155
+ # Do not load excluded devices
156
+ for device in containers.copy():
157
+ if device.name in exclude_devices:
158
+ containers.remove(device)
159
+
111
160
  return _load_devices(*containers)
112
161
 
113
162
 
@@ -132,7 +181,7 @@ def _load_devices(*containers: happi.HappiItem):
132
181
  return dev_namespace.__dict__
133
182
 
134
183
 
135
- def get_lightpath(db, hutch) -> LightController:
184
+ def get_lightpath(db: str, hutch: str) -> LightController:
136
185
  """
137
186
  Create a ``lightpath.LightController`` from relevant ``happi`` objects.
138
187
 
@@ -155,10 +204,14 @@ def get_lightpath(db, hutch) -> LightController:
155
204
  if None in (lightpath, beamlines):
156
205
  logger.warning('Lightpath module is not available.')
157
206
  return None
207
+
158
208
  # Load the happi Client
159
209
  client = happi.Client(path=db)
210
+
160
211
  # Allow the lightpath module to create a path
161
212
  lc = lightpath.LightController(client, endstations=[hutch.upper()])
213
+
162
214
  # Return paths (names only) seen by the LightController
163
215
  # avoid loding the devices so hutch-python can keep track of it
216
+
164
217
  return lc
@@ -58,11 +58,11 @@ class IPythonSessionTimer:
58
58
  ipython.events.register('pre_run_cell', self._set_user_active)
59
59
  ipython.events.register('post_run_cell', self._set_user_inactive)
60
60
 
61
- def _set_user_active(self):
61
+ def _set_user_active(self, *args, **kwargs):
62
62
  self.user_active = True
63
63
  self.last_active_time = time.monotonic()
64
64
 
65
- def _set_user_inactive(self):
65
+ def _set_user_inactive(self, *args, **kwargs):
66
66
  self.user_active = False
67
67
  self.last_active_time = time.monotonic()
68
68
 
@@ -297,6 +297,33 @@ def load_conf(conf, hutch_dir=None, args=None):
297
297
  daq_platform = 0
298
298
  logger.info('Selected default hutch-python daq platform: 0')
299
299
 
300
+ try:
301
+ # This is a list of all devices that should not be loaded
302
+ exclude_devices = conf['exclude_devices']
303
+ if not isinstance(exclude_devices, list):
304
+ logger.error(
305
+ 'Invalid exclude_devices conf, must be a list.')
306
+ exclude_devices = []
307
+ else:
308
+ exclude_devices = [device_name.strip()
309
+ for device_name in exclude_devices]
310
+ except KeyError:
311
+ exclude_devices = []
312
+ logger.info(
313
+ 'Exclude_devices has not been set in conf. Will load all devices.')
314
+
315
+ try:
316
+ # These are the additional devices to load
317
+ additional_devices = conf['additional_devices']
318
+ for search_val in additional_devices.values():
319
+ if not isinstance(search_val, dict):
320
+ logger.error(
321
+ 'Invalid additional_devices conf, must be a dictionary of dictionaries.')
322
+ except KeyError:
323
+ additional_devices = {}
324
+ logger.info(
325
+ 'Additional_devices has not been set in conf. No additional devices will be loaded.')
326
+
300
327
  # Set the session timeout duration
301
328
  try:
302
329
  hutch_python.ipython_session_timer.configure_timeout(
@@ -304,7 +331,7 @@ def load_conf(conf, hutch_dir=None, args=None):
304
331
  except KeyError:
305
332
  hutch_python.ipython_session_timer.configure_timeout(172800)
306
333
  logger.info(
307
- 'Missing session_timer value from conf. Set default value to 172800 seconds (48 hours).')
334
+ 'Missing session_timer value from conf. Session will time out in 48 hours.')
308
335
 
309
336
  # Make cache namespace
310
337
  cache = LoadCache((hutch or 'hutch') + '.db', hutch_dir=hutch_dir)
@@ -460,7 +487,8 @@ def load_conf(conf, hutch_dir=None, args=None):
460
487
  lc = get_lightpath(db, hutch)
461
488
 
462
489
  # Gather relevant objects given the BeamPath
463
- happi_objs = get_happi_objs(db, lc, hutch, load_level=load_level)
490
+ happi_objs = get_happi_objs(
491
+ db, lc, hutch, load_level=load_level, exclude_devices=exclude_devices, additional_devices=additional_devices)
464
492
  cache(**happi_objs)
465
493
 
466
494
  # create and store beampath
@@ -568,10 +596,12 @@ def load_conf(conf, hutch_dir=None, args=None):
568
596
  path.mkdir()
569
597
  path.chmod(0o777)
570
598
  if experiment is None:
571
- setup_preset_paths(hutch=beamline_presets)
599
+ setup_preset_paths(hutch=beamline_presets,
600
+ defer_loading=True)
572
601
  else:
573
602
  setup_preset_paths(hutch=beamline_presets,
574
- exp=experiment_presets)
603
+ exp=experiment_presets,
604
+ defer_loading=True)
575
605
 
576
606
  # configure objects
577
607
  if obj_config is not None:
@@ -0,0 +1,49 @@
1
+ """
2
+ Initialize the ELogPoster callback and subscribe it to the RunEngine
3
+
4
+ Startup script files to be run after ipython is initialized via:
5
+ ``c.InteractiveTerminalApp.exec_files``
6
+
7
+ Code here will take executed after both IPython has been loaded and
8
+ the namespace has been populated with hutch objects.
9
+
10
+ These will be run as standalone python files, and should not be
11
+ imported from.
12
+ """
13
+
14
+
15
+ def _configure_elog_poster():
16
+ import IPython
17
+ from nabs.callbacks import ELogPoster
18
+
19
+ from hutch_python.utils import safe_load
20
+
21
+ with safe_load('ELogPoster'):
22
+ try:
23
+ from bluesky.run_engine import RunEngine
24
+ from elog import HutchELog
25
+ except ImportError:
26
+ raise RuntimeError("A required module is missing, skip ElogPoster")
27
+
28
+ # RE, elog will already exist by now, if not we fail and skip.
29
+ # Some effort to give better error message for the logs.
30
+ try:
31
+ elog = globals()['elog']
32
+ except KeyError:
33
+ raise RuntimeError("elog not loaded, skip ElogPoster")
34
+ try:
35
+ RE = globals()['RE']
36
+ except KeyError:
37
+ raise RuntimeError("RE not loaded, skip ElogPoster")
38
+ # Even if they exist, things can go wrong if the user accidentally clobbers the name
39
+ if not isinstance(elog, HutchELog):
40
+ raise RuntimeError("elog replaced, skip ELogPoster")
41
+ if not isinstance(RE, RunEngine):
42
+ raise RuntimeError("RE replaced, skip ELogPoster")
43
+
44
+ elogc = ELogPoster(elog, IPython.get_ipython())
45
+ RE.subscribe(elogc)
46
+
47
+
48
+ if __name__ == '__main__':
49
+ _configure_elog_poster()
@@ -0,0 +1,15 @@
1
+ hutch: tst
2
+
3
+ # Our test happi database has the following configuration:
4
+ # tst_device_3 (inactive)
5
+
6
+ # z +-> (0.8) (1.0) (2.0)
7
+ # X0 -- tst_device_5 ------ tst_device_1 -- test_device_2 -- "TST"
8
+ # \
9
+ # Z0 -- tst_device_4 -- tst_device_6
10
+ # z +-> (0.85) (1.85)
11
+ db: happi_db.json
12
+
13
+ load: tst.beamline
14
+
15
+ experiment: tstx010