apsbits 2.0.1rc1__tar.gz → 2.0.3__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 (144) hide show
  1. {apsbits-2.0.1rc1 → apsbits-2.0.3}/HISTORY.rst +11 -1
  2. {apsbits-2.0.1rc1 → apsbits-2.0.3}/PKG-INFO +110 -1
  3. apsbits-2.0.3/README.md +147 -0
  4. {apsbits-2.0.1rc1 → apsbits-2.0.3}/apsbits.egg-info/PKG-INFO +110 -1
  5. {apsbits-2.0.1rc1 → apsbits-2.0.3}/apsbits.egg-info/SOURCES.txt +7 -0
  6. apsbits-2.0.3/docs/source/api/generated/apsbits.api.create_new_instrument.rst +14 -0
  7. apsbits-2.0.3/docs/source/api/generated/apsbits.api.delete_instrument.rst +14 -0
  8. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/generated/apsbits.demo_instrument.callbacks.demo_nexus_callback.rst +1 -1
  9. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/generated/apsbits.demo_instrument.callbacks.demo_spec_callback.rst +9 -3
  10. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/generated/apsbits.demo_instrument.rst +2 -0
  11. apsbits-2.0.3/docs/source/api/generated/apsbits.demo_instrument.suspenders.rst +4 -0
  12. apsbits-2.0.3/docs/source/api/generated/apsbits.demo_instrument.utils.rst +4 -0
  13. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/generated/apsbits.utils.config_loaders.rst +1 -0
  14. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/generated/apsbits.utils.controls_setup.rst +6 -7
  15. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/generated/apsbits.utils.helper_functions.rst +1 -0
  16. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/guides/setting_iconfig.rst +60 -4
  17. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/__init__.py +0 -4
  18. apsbits-2.0.3/src/apsbits/_version.py +24 -0
  19. apsbits-2.0.3/src/apsbits/core/__init__.py +1 -0
  20. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/core/best_effort_init.py +0 -1
  21. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/core/catalog_init.py +3 -4
  22. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/core/instrument_init.py +0 -1
  23. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/core/run_engine_init.py +1 -2
  24. apsbits-2.0.3/src/apsbits/core/session_setup.py +20 -0
  25. apsbits-2.0.3/src/apsbits/demo_instrument/callbacks/demo_nexus_callback.py +51 -0
  26. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/demo_instrument/callbacks/demo_spec_callback.py +26 -19
  27. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/demo_instrument/plans/sim_plans.py +0 -1
  28. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/demo_instrument/startup.py +7 -9
  29. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/demo_scripts/qs_host.sh +11 -6
  30. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/tests/test_delete_instrument.py +5 -3
  31. apsbits-2.0.3/src/apsbits/tests/test_import_purity.py +68 -0
  32. apsbits-2.0.3/src/apsbits/tests/test_side_effect_fixes.py +90 -0
  33. apsbits-2.0.3/src/apsbits/utils/__init__.py +1 -0
  34. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/utils/baseline_setup.py +0 -1
  35. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/utils/logging_setup.py +4 -3
  36. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/utils/metadata.py +59 -39
  37. apsbits-2.0.1rc1/README.md +0 -38
  38. apsbits-2.0.1rc1/src/apsbits/_version.py +0 -34
  39. apsbits-2.0.1rc1/src/apsbits/core/__init__.py +0 -11
  40. apsbits-2.0.1rc1/src/apsbits/demo_instrument/callbacks/demo_nexus_callback.py +0 -60
  41. apsbits-2.0.1rc1/src/apsbits/utils/__init__.py +0 -5
  42. {apsbits-2.0.1rc1 → apsbits-2.0.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  43. {apsbits-2.0.1rc1 → apsbits-2.0.3}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  44. {apsbits-2.0.1rc1 → apsbits-2.0.3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  45. {apsbits-2.0.1rc1 → apsbits-2.0.3}/.github/ISSUE_TEMPLATE/other.md +0 -0
  46. {apsbits-2.0.1rc1 → apsbits-2.0.3}/.github/ISSUE_TEMPLATE/question-issue-template.md +0 -0
  47. {apsbits-2.0.1rc1 → apsbits-2.0.3}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  48. {apsbits-2.0.1rc1 → apsbits-2.0.3}/.github/dependabot.yml +0 -0
  49. {apsbits-2.0.1rc1 → apsbits-2.0.3}/.github/workflows/code.yml +0 -0
  50. {apsbits-2.0.1rc1 → apsbits-2.0.3}/.github/workflows/docs.yml +0 -0
  51. {apsbits-2.0.1rc1 → apsbits-2.0.3}/.github/workflows/pypi.yml +0 -0
  52. {apsbits-2.0.1rc1 → apsbits-2.0.3}/.gitignore +0 -0
  53. {apsbits-2.0.1rc1 → apsbits-2.0.3}/.pre-commit-config.yaml +0 -0
  54. {apsbits-2.0.1rc1 → apsbits-2.0.3}/LICENSE +0 -0
  55. {apsbits-2.0.1rc1 → apsbits-2.0.3}/apsbits.egg-info/dependency_links.txt +0 -0
  56. {apsbits-2.0.1rc1 → apsbits-2.0.3}/apsbits.egg-info/entry_points.txt +0 -0
  57. {apsbits-2.0.1rc1 → apsbits-2.0.3}/apsbits.egg-info/requires.txt +0 -0
  58. {apsbits-2.0.1rc1 → apsbits-2.0.3}/apsbits.egg-info/top_level.txt +0 -0
  59. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/Makefile +0 -0
  60. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/make.bat +0 -0
  61. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/resources/create-repository-name.webp +0 -0
  62. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/resources/create-repository-owner.webp +0 -0
  63. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/resources/demo.ipynb +0 -0
  64. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/resources/use-this-template-button.webp +0 -0
  65. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/_static/.gitkeep +0 -0
  66. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/api.rst +0 -0
  67. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/core.rst +0 -0
  68. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/demo_instrument.rst +0 -0
  69. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/demo_qserver.rst +0 -0
  70. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/generated/apsbits.core.best_effort_init.rst +0 -0
  71. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/generated/apsbits.core.catalog_init.rst +0 -0
  72. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/generated/apsbits.core.run_engine_init.rst +0 -0
  73. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/generated/apsbits.demo_instrument.callbacks.rst +0 -0
  74. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/generated/apsbits.demo_instrument.configs.rst +0 -0
  75. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/generated/apsbits.demo_instrument.devices.rst +0 -0
  76. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/generated/apsbits.demo_instrument.plans.rst +0 -0
  77. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/generated/apsbits.demo_instrument.plans.sim_plans.rst +0 -0
  78. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/generated/apsbits.demo_instrument.startup.rst +0 -0
  79. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/generated/apsbits.demo_qserver.rst +0 -0
  80. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/generated/apsbits.utils.logging_setup.rst +0 -0
  81. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/generated/apsbits.utils.metadata.rst +0 -0
  82. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/generated/apsbits.utils.stored_dict.rst +0 -0
  83. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/index.rst +0 -0
  84. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/api/utils.rst +0 -0
  85. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/bits_overview.rst +0 -0
  86. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/conf.py +0 -0
  87. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/deprecated/console.rst +0 -0
  88. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/deprecated/dm.md +0 -0
  89. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/deprecated/logging_config.rst +0 -0
  90. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/deprecated/notebook.rst +0 -0
  91. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/deprecated/script.rst +0 -0
  92. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/guides/creating_devices.rst +0 -0
  93. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/guides/creating_instrument.rst +0 -0
  94. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/guides/developing_bits.rst +0 -0
  95. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/guides/dm.rst +0 -0
  96. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/guides/index.rst +0 -0
  97. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/guides/logging.rst +0 -0
  98. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/guides/qserver.rst +0 -0
  99. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/guides/qserver_service.rst +0 -0
  100. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/guides/sessions.rst +0 -0
  101. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/guides/startup.rst +0 -0
  102. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/guides/template_creation.rst +0 -0
  103. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/history.rst +0 -0
  104. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/index.rst +0 -0
  105. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/install.rst +0 -0
  106. {apsbits-2.0.1rc1 → apsbits-2.0.3}/docs/source/license.rst +0 -0
  107. {apsbits-2.0.1rc1 → apsbits-2.0.3}/pyproject.toml +0 -0
  108. {apsbits-2.0.1rc1 → apsbits-2.0.3}/setup.cfg +0 -0
  109. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/api/__init__.py +0 -0
  110. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/api/create_new_instrument.py +0 -0
  111. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/api/delete_instrument.py +0 -0
  112. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/api/run_instrument.py +0 -0
  113. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/configs/logging.yml +0 -0
  114. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/demo_instrument/README.md +0 -0
  115. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/demo_instrument/__init__.py +0 -0
  116. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/demo_instrument/callbacks/__init__.py +0 -0
  117. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/demo_instrument/configs/__init__.py +0 -0
  118. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/demo_instrument/configs/devices.yml +0 -0
  119. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/demo_instrument/configs/devices_aps_only.yml +0 -0
  120. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/demo_instrument/configs/extra_logging.yml +0 -0
  121. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/demo_instrument/configs/iconfig.yml +0 -0
  122. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/demo_instrument/devices/__init__.py +0 -0
  123. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/demo_instrument/plans/__init__.py +0 -0
  124. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/demo_instrument/qserver/qs-config.yml +0 -0
  125. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/demo_instrument/qserver/user_group_permissions.yaml +0 -0
  126. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/demo_instrument/suspenders/__init__.py +0 -0
  127. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/demo_instrument/utils/__init__.py +0 -0
  128. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/py.typed +0 -0
  129. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/tests/__init__.py +0 -0
  130. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/tests/conftest.py +0 -0
  131. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/tests/test_catalog_init.py +0 -0
  132. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/tests/test_config.py +0 -0
  133. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/tests/test_controls_setup.py +0 -0
  134. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/tests/test_device_factories.py +0 -0
  135. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/tests/test_general.py +0 -0
  136. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/tests/test_make_devices.py +0 -0
  137. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/tests/test_run_instrument.py +0 -0
  138. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/tests/test_stored_dict.py +0 -0
  139. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/utils/aps_functions.py +0 -0
  140. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/utils/config_loaders.py +0 -0
  141. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/utils/controls_setup.py +0 -0
  142. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/utils/helper_functions.py +0 -0
  143. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/utils/sim_creator.py +0 -0
  144. {apsbits-2.0.1rc1 → apsbits-2.0.3}/src/apsbits/utils/stored_dict.py +0 -0
@@ -30,7 +30,7 @@ describe future plans.
30
30
  .. Coming release content can be gathered here.
31
31
  Some people object to publishing unreleased changes.
32
32
 
33
- 2.0.1
33
+ 2.0.2
34
34
  #####
35
35
 
36
36
  release expected ?
@@ -46,6 +46,16 @@ describe future plans.
46
46
  * Bump iconfig version to 2.0.1 for the baseline addition.
47
47
  * Remove run_engine section from QS config.yml file and pin QS to 0.0.22+.
48
48
 
49
+ 2.0.1
50
+ #####
51
+
52
+ released 2026-01-13
53
+
54
+ Enhancements
55
+ ------------
56
+
57
+ * add support for TILED_PROFILE_NAME & TILED_PATH_NAME
58
+
49
59
  2.0.0 (PyPI) and 1.0.6 (repository)
50
60
  ###################################
51
61
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: apsbits
3
- Version: 2.0.1rc1
3
+ Version: 2.0.3
4
4
  Summary: Model of a Bluesky Data Acquisition Instrument in console, notebook, & queueserver.
5
5
  Author-email: Eric Codrea <ecodrea@anl.gov>, Pete Jemian <prjemian+instrument@gmail.com>, Rafael Vescovi <rvescovi@anl.gov>
6
6
  Maintainer-email: Eric Codrea <ecodrea@anl.gov>, Pete Jemian <prjemian+instrument@gmail.com>, Rafael Vescovi <rvescovi@anl.gov>
@@ -94,6 +94,115 @@ pip install apsbits
94
94
 
95
95
  For development please reference our documentation
96
96
 
97
+ ## Startup Architecture
98
+
99
+ When a user runs `from apsbits.demo_instrument.startup import *`, the following
100
+ import and initialization sequence executes. No module runs code on import.
101
+ All initialization flows through `startup.py` via explicit function calls.
102
+
103
+ ### Module Dependency Graph
104
+
105
+ Arrows show import direction. No circular imports exist.
106
+
107
+ ```mermaid
108
+ graph LR
109
+ subgraph utils["apsbits.utils (base layer)"]
110
+ config_loaders
111
+ aps_functions
112
+ controls_setup
113
+ helper_functions --> config_loaders
114
+ logging_setup -.->|"inside fn"| config_loaders
115
+ baseline_setup --> config_loaders
116
+ metadata -.->|"inside fn"| apsbits_init
117
+ stored_dict -.->|"inside fn"| config_loaders
118
+ sim_creator --> helper_functions
119
+ end
120
+
121
+ subgraph core["apsbits.core (middle layer)"]
122
+ core_init["core/__init__"] --> helper_functions
123
+ best_effort_init --> helper_functions
124
+ catalog_init
125
+ instrument_init --> config_loaders
126
+ run_engine_init --> controls_setup
127
+ run_engine_init --> metadata
128
+ run_engine_init --> stored_dict
129
+ end
130
+
131
+ subgraph demo["demo_instrument (top layer)"]
132
+ startup
133
+ nexus_cb["callbacks/nexus"]
134
+ spec_cb["callbacks/spec"]
135
+ sim_plans --> instrument_init
136
+ end
137
+
138
+ subgraph api["apsbits.api"]
139
+ create_new_instrument
140
+ delete_instrument
141
+ run_instrument --> instrument_init
142
+ end
143
+
144
+ apsbits_init["apsbits/__init__"]
145
+
146
+ startup --> logging_setup
147
+ startup --> core_init
148
+ startup --> best_effort_init
149
+ startup --> catalog_init
150
+ startup --> instrument_init
151
+ startup --> run_engine_init
152
+ startup --> helper_functions
153
+ startup --> config_loaders
154
+ startup --> baseline_setup
155
+ startup --> aps_functions
156
+ startup -.->|"if enabled"| nexus_cb
157
+ startup -.->|"if enabled"| spec_cb
158
+ startup --> sim_plans
159
+ ```
160
+
161
+ Solid arrows = module-level imports. Dashed arrows = conditional or function-level imports.
162
+
163
+ ### Initialization Sequence
164
+
165
+ Everything is called explicitly by `startup.py` in this order:
166
+ ```mermaid
167
+ graph TD
168
+ S["startup.py"] -->|1| A["configure_logging()"]
169
+ A -->|reads| A1[("logging.yml")]
170
+ S -->|2| B["prepare_bits()"]
171
+ S -->|3| C["load_config()"]
172
+ C -->|reads| C1[("iconfig.yml")]
173
+ S -->|4| D["configure_logging(extra)"]
174
+ D -->|reads| D1[("extra_logging.yml")]
175
+ S -->|5| E["init_instrument()"]
176
+ E -->|creates| E1["instrument, oregistry"]
177
+ S -->|6| F["init_bec_peaks(iconfig)"]
178
+ F -->|creates| F1["bec, peaks"]
179
+ S -->|7| G["init_catalog(iconfig)"]
180
+ G -->|creates| G1["cat"]
181
+ S -->|8| H["init_RE(iconfig, ...)"]
182
+ H -->|creates| H1["RE, sd"]
183
+ S -->|"9 (if enabled)"| I["nxwriter_init(RE, iconfig)"]
184
+ I -->|creates| I1["nxwriter"]
185
+ S -->|"10 (if enabled)"| J["init_specwriter_with_RE(RE, iconfig)"]
186
+ J -->|creates| J1["specwriter"]
187
+ S -->|11| K["make_devices(...)"]
188
+ K -->|reads| K1[("devices.yml")]
189
+ S -->|12| L["setup_baseline_stream()"]
190
+
191
+ style S fill:#fff3e0
192
+ style A1 fill:#f3e5f5
193
+ style C1 fill:#f3e5f5
194
+ style D1 fill:#f3e5f5
195
+ style K1 fill:#f3e5f5
196
+ style E1 fill:#c8e6c9
197
+ style F1 fill:#c8e6c9
198
+ style G1 fill:#c8e6c9
199
+ style H1 fill:#c8e6c9
200
+ style I1 fill:#c8e6c9
201
+ style J1 fill:#c8e6c9
202
+ ```
203
+
204
+ Purple = YAML config files read from disk. Green = objects available in your session.
205
+
97
206
  ## Testing the apsbits base installation
98
207
 
99
208
  On an ipython console
@@ -0,0 +1,147 @@
1
+ # APSBITS: Template Package for Bluesky Instruments
2
+
3
+ | PyPI | Coverage |
4
+ | --- | --- |
5
+ [![PyPi](https://img.shields.io/pypi/v/apsbits.svg)](https://pypi.python.org/pypi/apsbits) | [![Coverage Status](https://coveralls.io/repos/github/BCDA-APS/BITS/badge.svg?branch=main)](https://coveralls.io/github/BCDA-APS/BITS?branch=main) |
6
+
7
+ BITS: **B**luesky **I**nstrument **T**emplate **S**tructure
8
+
9
+ Template of a Bluesky Data Acquisition Instrument in console, notebook, &
10
+ queueserver.
11
+
12
+ ## Production use of BITS
13
+
14
+ Please create a bits instrument using our template repository: https://github.com/BCDA-APS/DEMO-BITS
15
+
16
+
17
+ ## Installing the BITS Package
18
+
19
+ ```bash
20
+ export INSTALL_ENVIRONMENT_NAME=apsbits_env
21
+ conda create -y -n "${INSTALL_ENVIRONMENT_NAME}" python=3.11 pyepics
22
+ conda activate "${INSTALL_ENVIRONMENT_NAME}"
23
+ pip install apsbits
24
+ ```
25
+
26
+ For development please reference our documentation
27
+
28
+ ## Startup Architecture
29
+
30
+ When a user runs `from apsbits.demo_instrument.startup import *`, the following
31
+ import and initialization sequence executes. No module runs code on import.
32
+ All initialization flows through `startup.py` via explicit function calls.
33
+
34
+ ### Module Dependency Graph
35
+
36
+ Arrows show import direction. No circular imports exist.
37
+
38
+ ```mermaid
39
+ graph LR
40
+ subgraph utils["apsbits.utils (base layer)"]
41
+ config_loaders
42
+ aps_functions
43
+ controls_setup
44
+ helper_functions --> config_loaders
45
+ logging_setup -.->|"inside fn"| config_loaders
46
+ baseline_setup --> config_loaders
47
+ metadata -.->|"inside fn"| apsbits_init
48
+ stored_dict -.->|"inside fn"| config_loaders
49
+ sim_creator --> helper_functions
50
+ end
51
+
52
+ subgraph core["apsbits.core (middle layer)"]
53
+ core_init["core/__init__"] --> helper_functions
54
+ best_effort_init --> helper_functions
55
+ catalog_init
56
+ instrument_init --> config_loaders
57
+ run_engine_init --> controls_setup
58
+ run_engine_init --> metadata
59
+ run_engine_init --> stored_dict
60
+ end
61
+
62
+ subgraph demo["demo_instrument (top layer)"]
63
+ startup
64
+ nexus_cb["callbacks/nexus"]
65
+ spec_cb["callbacks/spec"]
66
+ sim_plans --> instrument_init
67
+ end
68
+
69
+ subgraph api["apsbits.api"]
70
+ create_new_instrument
71
+ delete_instrument
72
+ run_instrument --> instrument_init
73
+ end
74
+
75
+ apsbits_init["apsbits/__init__"]
76
+
77
+ startup --> logging_setup
78
+ startup --> core_init
79
+ startup --> best_effort_init
80
+ startup --> catalog_init
81
+ startup --> instrument_init
82
+ startup --> run_engine_init
83
+ startup --> helper_functions
84
+ startup --> config_loaders
85
+ startup --> baseline_setup
86
+ startup --> aps_functions
87
+ startup -.->|"if enabled"| nexus_cb
88
+ startup -.->|"if enabled"| spec_cb
89
+ startup --> sim_plans
90
+ ```
91
+
92
+ Solid arrows = module-level imports. Dashed arrows = conditional or function-level imports.
93
+
94
+ ### Initialization Sequence
95
+
96
+ Everything is called explicitly by `startup.py` in this order:
97
+ ```mermaid
98
+ graph TD
99
+ S["startup.py"] -->|1| A["configure_logging()"]
100
+ A -->|reads| A1[("logging.yml")]
101
+ S -->|2| B["prepare_bits()"]
102
+ S -->|3| C["load_config()"]
103
+ C -->|reads| C1[("iconfig.yml")]
104
+ S -->|4| D["configure_logging(extra)"]
105
+ D -->|reads| D1[("extra_logging.yml")]
106
+ S -->|5| E["init_instrument()"]
107
+ E -->|creates| E1["instrument, oregistry"]
108
+ S -->|6| F["init_bec_peaks(iconfig)"]
109
+ F -->|creates| F1["bec, peaks"]
110
+ S -->|7| G["init_catalog(iconfig)"]
111
+ G -->|creates| G1["cat"]
112
+ S -->|8| H["init_RE(iconfig, ...)"]
113
+ H -->|creates| H1["RE, sd"]
114
+ S -->|"9 (if enabled)"| I["nxwriter_init(RE, iconfig)"]
115
+ I -->|creates| I1["nxwriter"]
116
+ S -->|"10 (if enabled)"| J["init_specwriter_with_RE(RE, iconfig)"]
117
+ J -->|creates| J1["specwriter"]
118
+ S -->|11| K["make_devices(...)"]
119
+ K -->|reads| K1[("devices.yml")]
120
+ S -->|12| L["setup_baseline_stream()"]
121
+
122
+ style S fill:#fff3e0
123
+ style A1 fill:#f3e5f5
124
+ style C1 fill:#f3e5f5
125
+ style D1 fill:#f3e5f5
126
+ style K1 fill:#f3e5f5
127
+ style E1 fill:#c8e6c9
128
+ style F1 fill:#c8e6c9
129
+ style G1 fill:#c8e6c9
130
+ style H1 fill:#c8e6c9
131
+ style I1 fill:#c8e6c9
132
+ style J1 fill:#c8e6c9
133
+ ```
134
+
135
+ Purple = YAML config files read from disk. Green = objects available in your session.
136
+
137
+ ## Testing the apsbits base installation
138
+
139
+ On an ipython console
140
+
141
+ ```py
142
+ from apsbits.demo_instrument.startup import *
143
+ listobjects()
144
+ RE(sim_print_plan())
145
+ RE(sim_count_plan())
146
+ RE(sim_rel_scan_plan())
147
+ ```
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: apsbits
3
- Version: 2.0.1rc1
3
+ Version: 2.0.3
4
4
  Summary: Model of a Bluesky Data Acquisition Instrument in console, notebook, & queueserver.
5
5
  Author-email: Eric Codrea <ecodrea@anl.gov>, Pete Jemian <prjemian+instrument@gmail.com>, Rafael Vescovi <rvescovi@anl.gov>
6
6
  Maintainer-email: Eric Codrea <ecodrea@anl.gov>, Pete Jemian <prjemian+instrument@gmail.com>, Rafael Vescovi <rvescovi@anl.gov>
@@ -94,6 +94,115 @@ pip install apsbits
94
94
 
95
95
  For development please reference our documentation
96
96
 
97
+ ## Startup Architecture
98
+
99
+ When a user runs `from apsbits.demo_instrument.startup import *`, the following
100
+ import and initialization sequence executes. No module runs code on import.
101
+ All initialization flows through `startup.py` via explicit function calls.
102
+
103
+ ### Module Dependency Graph
104
+
105
+ Arrows show import direction. No circular imports exist.
106
+
107
+ ```mermaid
108
+ graph LR
109
+ subgraph utils["apsbits.utils (base layer)"]
110
+ config_loaders
111
+ aps_functions
112
+ controls_setup
113
+ helper_functions --> config_loaders
114
+ logging_setup -.->|"inside fn"| config_loaders
115
+ baseline_setup --> config_loaders
116
+ metadata -.->|"inside fn"| apsbits_init
117
+ stored_dict -.->|"inside fn"| config_loaders
118
+ sim_creator --> helper_functions
119
+ end
120
+
121
+ subgraph core["apsbits.core (middle layer)"]
122
+ core_init["core/__init__"] --> helper_functions
123
+ best_effort_init --> helper_functions
124
+ catalog_init
125
+ instrument_init --> config_loaders
126
+ run_engine_init --> controls_setup
127
+ run_engine_init --> metadata
128
+ run_engine_init --> stored_dict
129
+ end
130
+
131
+ subgraph demo["demo_instrument (top layer)"]
132
+ startup
133
+ nexus_cb["callbacks/nexus"]
134
+ spec_cb["callbacks/spec"]
135
+ sim_plans --> instrument_init
136
+ end
137
+
138
+ subgraph api["apsbits.api"]
139
+ create_new_instrument
140
+ delete_instrument
141
+ run_instrument --> instrument_init
142
+ end
143
+
144
+ apsbits_init["apsbits/__init__"]
145
+
146
+ startup --> logging_setup
147
+ startup --> core_init
148
+ startup --> best_effort_init
149
+ startup --> catalog_init
150
+ startup --> instrument_init
151
+ startup --> run_engine_init
152
+ startup --> helper_functions
153
+ startup --> config_loaders
154
+ startup --> baseline_setup
155
+ startup --> aps_functions
156
+ startup -.->|"if enabled"| nexus_cb
157
+ startup -.->|"if enabled"| spec_cb
158
+ startup --> sim_plans
159
+ ```
160
+
161
+ Solid arrows = module-level imports. Dashed arrows = conditional or function-level imports.
162
+
163
+ ### Initialization Sequence
164
+
165
+ Everything is called explicitly by `startup.py` in this order:
166
+ ```mermaid
167
+ graph TD
168
+ S["startup.py"] -->|1| A["configure_logging()"]
169
+ A -->|reads| A1[("logging.yml")]
170
+ S -->|2| B["prepare_bits()"]
171
+ S -->|3| C["load_config()"]
172
+ C -->|reads| C1[("iconfig.yml")]
173
+ S -->|4| D["configure_logging(extra)"]
174
+ D -->|reads| D1[("extra_logging.yml")]
175
+ S -->|5| E["init_instrument()"]
176
+ E -->|creates| E1["instrument, oregistry"]
177
+ S -->|6| F["init_bec_peaks(iconfig)"]
178
+ F -->|creates| F1["bec, peaks"]
179
+ S -->|7| G["init_catalog(iconfig)"]
180
+ G -->|creates| G1["cat"]
181
+ S -->|8| H["init_RE(iconfig, ...)"]
182
+ H -->|creates| H1["RE, sd"]
183
+ S -->|"9 (if enabled)"| I["nxwriter_init(RE, iconfig)"]
184
+ I -->|creates| I1["nxwriter"]
185
+ S -->|"10 (if enabled)"| J["init_specwriter_with_RE(RE, iconfig)"]
186
+ J -->|creates| J1["specwriter"]
187
+ S -->|11| K["make_devices(...)"]
188
+ K -->|reads| K1[("devices.yml")]
189
+ S -->|12| L["setup_baseline_stream()"]
190
+
191
+ style S fill:#fff3e0
192
+ style A1 fill:#f3e5f5
193
+ style C1 fill:#f3e5f5
194
+ style D1 fill:#f3e5f5
195
+ style K1 fill:#f3e5f5
196
+ style E1 fill:#c8e6c9
197
+ style F1 fill:#c8e6c9
198
+ style G1 fill:#c8e6c9
199
+ style H1 fill:#c8e6c9
200
+ style I1 fill:#c8e6c9
201
+ style J1 fill:#c8e6c9
202
+ ```
203
+
204
+ Purple = YAML config files read from disk. Green = objects available in your session.
205
+
97
206
  ## Testing the apsbits base installation
98
207
 
99
208
  On an ipython console
@@ -39,6 +39,8 @@ docs/source/api/demo_instrument.rst
39
39
  docs/source/api/demo_qserver.rst
40
40
  docs/source/api/index.rst
41
41
  docs/source/api/utils.rst
42
+ docs/source/api/generated/apsbits.api.create_new_instrument.rst
43
+ docs/source/api/generated/apsbits.api.delete_instrument.rst
42
44
  docs/source/api/generated/apsbits.core.best_effort_init.rst
43
45
  docs/source/api/generated/apsbits.core.catalog_init.rst
44
46
  docs/source/api/generated/apsbits.core.run_engine_init.rst
@@ -51,6 +53,8 @@ docs/source/api/generated/apsbits.demo_instrument.plans.rst
51
53
  docs/source/api/generated/apsbits.demo_instrument.plans.sim_plans.rst
52
54
  docs/source/api/generated/apsbits.demo_instrument.rst
53
55
  docs/source/api/generated/apsbits.demo_instrument.startup.rst
56
+ docs/source/api/generated/apsbits.demo_instrument.suspenders.rst
57
+ docs/source/api/generated/apsbits.demo_instrument.utils.rst
54
58
  docs/source/api/generated/apsbits.demo_qserver.rst
55
59
  docs/source/api/generated/apsbits.utils.config_loaders.rst
56
60
  docs/source/api/generated/apsbits.utils.controls_setup.rst
@@ -88,6 +92,7 @@ src/apsbits/core/best_effort_init.py
88
92
  src/apsbits/core/catalog_init.py
89
93
  src/apsbits/core/instrument_init.py
90
94
  src/apsbits/core/run_engine_init.py
95
+ src/apsbits/core/session_setup.py
91
96
  src/apsbits/demo_instrument/README.md
92
97
  src/apsbits/demo_instrument/__init__.py
93
98
  src/apsbits/demo_instrument/startup.py
@@ -115,8 +120,10 @@ src/apsbits/tests/test_controls_setup.py
115
120
  src/apsbits/tests/test_delete_instrument.py
116
121
  src/apsbits/tests/test_device_factories.py
117
122
  src/apsbits/tests/test_general.py
123
+ src/apsbits/tests/test_import_purity.py
118
124
  src/apsbits/tests/test_make_devices.py
119
125
  src/apsbits/tests/test_run_instrument.py
126
+ src/apsbits/tests/test_side_effect_fixes.py
120
127
  src/apsbits/tests/test_stored_dict.py
121
128
  src/apsbits/utils/__init__.py
122
129
  src/apsbits/utils/aps_functions.py
@@ -0,0 +1,14 @@
1
+ apsbits.api.create\_new\_instrument
2
+ ===================================
3
+
4
+ .. automodule:: apsbits.api.create_new_instrument
5
+
6
+
7
+ .. rubric:: Functions
8
+
9
+ .. autosummary::
10
+
11
+ copy_instrument
12
+ create_qserver_script
13
+ edit_qserver_folder
14
+ main
@@ -0,0 +1,14 @@
1
+ apsbits.api.delete\_instrument
2
+ ==============================
3
+
4
+ .. automodule:: apsbits.api.delete_instrument
5
+
6
+
7
+ .. rubric:: Functions
8
+
9
+ .. autosummary::
10
+
11
+ delete_instrument
12
+ get_instrument_paths
13
+ main
14
+ validate_instrument_name
@@ -1,5 +1,5 @@
1
1
  apsbits.demo\_instrument.callbacks.demo\_nexus\_callback
2
- ======================================================
2
+ ========================================================
3
3
 
4
4
  .. automodule:: apsbits.demo_instrument.callbacks.demo_nexus_callback
5
5
 
@@ -1,13 +1,19 @@
1
1
  apsbits.demo\_instrument.callbacks.demo\_spec\_callback
2
- =====================================================
2
+ =======================================================
3
3
 
4
4
  .. automodule:: apsbits.demo_instrument.callbacks.demo_spec_callback
5
5
 
6
6
 
7
+ .. rubric:: Module Attributes
8
+
9
+ .. autosummary::
10
+
11
+ specwriter
12
+
7
13
  .. rubric:: Functions
8
14
 
9
15
  .. autosummary::
10
16
 
11
- spec_comment
12
- newSpecFile
13
17
  init_specwriter_with_RE
18
+ newSpecFile
19
+ spec_comment
@@ -15,3 +15,5 @@
15
15
  devices
16
16
  plans
17
17
  startup
18
+ suspenders
19
+ utils
@@ -0,0 +1,4 @@
1
+ apsbits.demo\_instrument.suspenders
2
+ ===================================
3
+
4
+ .. automodule:: apsbits.demo_instrument.suspenders
@@ -0,0 +1,4 @@
1
+ apsbits.demo\_instrument.utils
2
+ ==============================
3
+
4
+ .. automodule:: apsbits.demo_instrument.utils
@@ -12,3 +12,4 @@
12
12
  load_config
13
13
  load_config_yaml
14
14
  update_config
15
+ validate_instrument_path
@@ -4,17 +4,16 @@
4
4
  .. automodule:: apsbits.utils.controls_setup
5
5
 
6
6
 
7
- .. rubric:: Module Attributes
8
-
9
- .. autosummary::
10
-
11
- oregistry
12
-
13
7
  .. rubric:: Functions
14
8
 
15
9
  .. autosummary::
16
10
 
17
11
  connect_scan_id_pv
18
- epics_scan_id_source
19
12
  set_control_layer
20
13
  set_timeouts
14
+
15
+ .. rubric:: Classes
16
+
17
+ .. autosummary::
18
+
19
+ EpicsScanIdSource
@@ -9,6 +9,7 @@
9
9
  .. autosummary::
10
10
 
11
11
  debug_python
12
+ dynamic_import
12
13
  get_xmode_level
13
14
  is_notebook
14
15
  mpl_setup
@@ -1,10 +1,67 @@
1
1
  Setting up your instrument
2
2
  ================================
3
3
 
4
- The iconfig file is a YAML file that contains the configuration for your instrument.
5
- It is used to set up the instrument preferences and settings. The iconfig file is
6
- located in the ``configs`` directory of your instrument package. Below we go through the settings available in the iconfig file.
4
+ The iconfig file is a YAML file that contains the configuration for your
5
+ instrument. It is used to set up the instrument preferences and settings. The
6
+ iconfig file is located in the ``configs`` directory of your instrument package.
7
+ Below we go through the settings available in the iconfig file.
7
8
 
9
+ CATALOG
10
+ ----------------
11
+
12
+ A *catalog* is where the data from a bluesky *run* (documents published by the
13
+ bluesky RunEngine) is saved.
14
+
15
+ ``TILED_PROFILE_NAME`` (preferred)
16
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17
+
18
+ Name of the Tiled profile to use.
19
+
20
+ If ``TILED_PROFILE_NAME`` is set, it takes precedence over ``DATABROKER_CATALOG``.
21
+
22
+ The tiled profile is a special file (see ``tiled profile --help``). It defines
23
+ a simple shortcut to the full Tiled server URI and API key necessary for write
24
+ access to the catalog. A full list of the profile names available to you
25
+ can be obtained with the command: ``tiled profile list``.
26
+
27
+ ``TILED_PATH_NAME`` (optional)
28
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
29
+
30
+ Optional *server-defined* path name provided by the Tiled server.
31
+
32
+ Important notes:
33
+
34
+ * ``TILED_PATH_NAME`` is a path provided by the tiled server. It is not a filesystem directory path.
35
+ * If your server only defines the tiled catalog at ``/``, do not define ``TILED_PATH_NAME``.
36
+ * Different Tiled server deployments may provide different path names.
37
+ * If omitted, the Tiled server default path is used.
38
+ * Setting ``TILED_PATH_NAME: "/"`` has been observed to cause a server error.
39
+ In that case, do **not** define ``TILED_PATH_NAME``.
40
+
41
+ Example
42
+ ++++++++++++++
43
+
44
+ Example excerpt from ``configs/iconfig.yml``:
45
+
46
+
47
+ .. code-block:: yaml
48
+ :linenos:
49
+
50
+ # Preferred Tiled configuration
51
+ TILED_PROFILE_NAME: raw
52
+ # Only set this if your server requires a non-default path:
53
+ TILED_PATH_NAME: /raw
54
+
55
+ Legacy configuration
56
+ +++++++++++++++++++++++++++++++++
57
+
58
+ ``DATABROKER_CATALOG`` (legacy)
59
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
60
+
61
+ ``DATABROKER_CATALOG`` is supported for backward compatibility, but
62
+ ``TILED_PROFILE_NAME`` (and optionally ``TILED_PATH_NAME``) is preferred.
63
+
64
+ If both are set, ``TILED_PROFILE_NAME`` is used.
8
65
 
9
66
  RUN_ENGINE
10
67
  -----------------------------
@@ -17,7 +74,6 @@ The ``RUN_ENGINE`` section contains the configuration for the run engine. The ru
17
74
  beamline_id: demo_instrument
18
75
  instrument_name: Most Glorious Scientific Instrument
19
76
  proposal_id: commissioning
20
- databroker_catalog: *databroker_catalog
21
77
 
22
78
  ### EPICS PV to use for the `scan_id`.
23
79
  ### Default: `RE.md["scan_id"]` (not using an EPICS PV)
@@ -2,10 +2,6 @@
2
2
 
3
3
  """Model Bluesky Data Acquisition Instrument."""
4
4
 
5
- from apsbits.utils.logging_setup import configure_logging
6
-
7
- configure_logging()
8
-
9
5
  __package__ = "apsbits"
10
6
  try:
11
7
  from setuptools_scm import get_version