TwoPy 0.3.2__tar.gz → 0.3.4__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 (262) hide show
  1. {twopy-0.3.2 → twopy-0.3.4}/PKG-INFO +2 -1
  2. {twopy-0.3.2 → twopy-0.3.4}/pyproject.toml +3 -2
  3. twopy-0.3.4/src/twopy/__init__.py +328 -0
  4. twopy-0.3.4/src/twopy/__init__.pyi +422 -0
  5. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/group_matching.py +23 -10
  6. twopy-0.3.4/src/twopy/napari/assets/twopy-app-icon-128.png +0 -0
  7. twopy-0.3.4/src/twopy/napari/assets/twopy-app-icon-16.png +0 -0
  8. twopy-0.3.4/src/twopy/napari/assets/twopy-app-icon-256.png +0 -0
  9. twopy-0.3.4/src/twopy/napari/assets/twopy-app-icon-32.png +0 -0
  10. twopy-0.3.4/src/twopy/napari/assets/twopy-app-icon-512.png +0 -0
  11. twopy-0.3.4/src/twopy/napari/assets/twopy-app-icon-64.png +0 -0
  12. twopy-0.3.4/src/twopy/napari/assets/twopy-app-icon.icns +0 -0
  13. twopy-0.3.4/src/twopy/napari/assets/twopy-app-icon.png +0 -0
  14. twopy-0.3.4/src/twopy/napari/empty_state.py +159 -0
  15. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/group_matching/images.py +17 -11
  16. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/group_matching/response_preview.py +17 -9
  17. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/group_matching/roi_assignment.py +106 -51
  18. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/group_matching/roi_cards.py +122 -38
  19. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/group_matching/window.py +1 -1
  20. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/launcher.py +86 -42
  21. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/docks/options_panel.py +9 -4
  22. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/docks/response_plot_widget.py +31 -0
  23. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/panels.py +5 -0
  24. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/session.py +9 -0
  25. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/state.py +65 -0
  26. twopy-0.3.4/src/twopy/napari/version_check.py +280 -0
  27. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/viewer.py +61 -18
  28. {twopy-0.3.2 → twopy-0.3.4}/src/twopy.egg-info/PKG-INFO +2 -1
  29. {twopy-0.3.2 → twopy-0.3.4}/src/twopy.egg-info/SOURCES.txt +12 -0
  30. {twopy-0.3.2 → twopy-0.3.4}/src/twopy.egg-info/requires.txt +1 -0
  31. {twopy-0.3.2 → twopy-0.3.4}/tests/test_group_matching.py +65 -28
  32. {twopy-0.3.2 → twopy-0.3.4}/tests/test_import.py +21 -0
  33. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari.py +93 -2
  34. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_group_matching_roi_cards.py +94 -12
  35. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_loaded_recordings.py +14 -10
  36. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_plot_controls.py +4 -0
  37. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_plot_widgets.py +123 -12
  38. {twopy-0.3.2 → twopy-0.3.4}/tests/test_packaging.py +44 -0
  39. twopy-0.3.4/tests/test_version_check.py +207 -0
  40. twopy-0.3.2/src/twopy/__init__.py +0 -309
  41. {twopy-0.3.2 → twopy-0.3.4}/README.md +0 -0
  42. {twopy-0.3.2 → twopy-0.3.4}/setup.cfg +0 -0
  43. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/_segments.py +0 -0
  44. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/_version.py +0 -0
  45. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/__init__.py +0 -0
  46. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/background_subtraction.py +0 -0
  47. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/dff.py +0 -0
  48. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/dff_options.py +0 -0
  49. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/epoch_mapping.py +0 -0
  50. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/kernels/__init__.py +0 -0
  51. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/kernels/_fitting.py +0 -0
  52. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/kernels/_stimulus.py +0 -0
  53. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/motion.py +0 -0
  54. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/persistence.py +0 -0
  55. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/response_context.py +0 -0
  56. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/response_maps.py +0 -0
  57. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/response_plotting.py +0 -0
  58. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/response_processing/__init__.py +0 -0
  59. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/response_processing/apply.py +0 -0
  60. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/response_processing/options.py +0 -0
  61. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/response_processing/persistence.py +0 -0
  62. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/response_processing/qc.py +0 -0
  63. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/response_processing/signals.py +0 -0
  64. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/response_window_options.py +0 -0
  65. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/responses.py +0 -0
  66. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/timing.py +0 -0
  67. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/trials.py +0 -0
  68. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis/workflow.py +0 -0
  69. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/analysis_cache.py +0 -0
  70. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/api.py +0 -0
  71. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/cache_inventory.py +0 -0
  72. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/calibrations/pixel_calibration_profiles.csv +0 -0
  73. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/calibrations/pixel_size.csv +0 -0
  74. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/config.example.yml +0 -0
  75. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/config.py +0 -0
  76. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/conversion/__init__.py +0 -0
  77. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/conversion/alignment_crop.py +0 -0
  78. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/conversion/api.py +0 -0
  79. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/conversion/hdf5_writing.py +0 -0
  80. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/conversion/matlab_values.py +0 -0
  81. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/conversion/orientation.py +0 -0
  82. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/conversion/source_loading.py +0 -0
  83. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/conversion/stimulus_code.py +0 -0
  84. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/conversion/types.py +0 -0
  85. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/converted.py +0 -0
  86. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/custom/__init__.py +0 -0
  87. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/custom/context.py +0 -0
  88. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/custom/discovery.py +0 -0
  89. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/custom/metadata.py +0 -0
  90. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/custom/native.py +0 -0
  91. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/custom/native_workflows/__init__.py +0 -0
  92. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/custom/native_workflows/direction_selectivity.py +0 -0
  93. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/custom/native_workflows/response_kernels.py +0 -0
  94. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/custom/parameters.py +0 -0
  95. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/custom/provenance.py +0 -0
  96. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/custom/registry.py +0 -0
  97. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/custom/results.py +0 -0
  98. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/custom/runner.py +0 -0
  99. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/custom/workflows.py +0 -0
  100. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/database/__init__.py +0 -0
  101. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/database/cache.py +0 -0
  102. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/database/catalog.py +0 -0
  103. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/database/connection.py +0 -0
  104. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/database/generic.py +0 -0
  105. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/database/modeled.py +0 -0
  106. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/database/search.py +0 -0
  107. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/database/sql.py +0 -0
  108. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/database/types.py +0 -0
  109. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/filenames.py +0 -0
  110. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/frame_ranges.py +0 -0
  111. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/hdf5_utils.py +0 -0
  112. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/inspection.py +0 -0
  113. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/matlab.py +0 -0
  114. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/__init__.py +0 -0
  115. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/__main__.py +0 -0
  116. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/controls.py +0 -0
  117. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/custom_tab.py +0 -0
  118. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/database_favorite_editor.py +0 -0
  119. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/database_favorites.py +0 -0
  120. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/database_search.py +0 -0
  121. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/dims.py +0 -0
  122. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/display.py +0 -0
  123. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/display_paths.py +0 -0
  124. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/errors.py +0 -0
  125. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/group_matching/__init__.py +0 -0
  126. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/group_matching/cards.py +0 -0
  127. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/group_matching/fov_assignment.py +0 -0
  128. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/group_matching/fov_cards.py +0 -0
  129. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/group_matching/protocols.py +0 -0
  130. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/group_matching/responses.py +0 -0
  131. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/group_matching/style.py +0 -0
  132. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/group_matching/tables.py +0 -0
  133. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/interactive.py +0 -0
  134. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/latest_worker.py +0 -0
  135. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/live_analysis.py +0 -0
  136. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/load_controller.py +0 -0
  137. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/load_progress.py +0 -0
  138. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/load_workflow.py +0 -0
  139. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/loaded_recordings_csv.py +0 -0
  140. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/loading.py +0 -0
  141. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/movie.py +0 -0
  142. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/output_routing.py +0 -0
  143. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/paths.py +0 -0
  144. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/__init__.py +0 -0
  145. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/data.py +0 -0
  146. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/dff_options.py +0 -0
  147. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/docks/__init__.py +0 -0
  148. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/docks/api.py +0 -0
  149. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/docks/dynamic_options.py +0 -0
  150. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/docks/paths.py +0 -0
  151. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/docks/plot_area.py +0 -0
  152. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/docks/response_map_area.py +0 -0
  153. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/docks/save_actions.py +0 -0
  154. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/docks/visibility_state.py +0 -0
  155. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/export.py +0 -0
  156. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/export_controls.py +0 -0
  157. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/form_controls.py +0 -0
  158. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/label_visibility.py +0 -0
  159. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/normalization_options.py +0 -0
  160. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/options.py +0 -0
  161. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/preview_strip.py +0 -0
  162. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/processing_options.py +0 -0
  163. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/response_map_colors.py +0 -0
  164. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/response_map_display.py +0 -0
  165. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/response_map_options.py +0 -0
  166. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/response_window_options.py +0 -0
  167. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/roi_generation/__init__.py +0 -0
  168. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/roi_generation/actions.py +0 -0
  169. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/roi_generation/controls.py +0 -0
  170. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/roi_generation/options.py +0 -0
  171. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/plotting/widgets.py +0 -0
  172. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/protocols.py +0 -0
  173. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/responses.py +0 -0
  174. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/roi.py +0 -0
  175. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/roi_signatures.py +0 -0
  176. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/sidebar.py +0 -0
  177. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/text.py +0 -0
  178. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/trial_timeline.py +0 -0
  179. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/napari/types.py +0 -0
  180. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/parity/__init__.py +0 -0
  181. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/parity/dff.py +0 -0
  182. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/parity/psycho5.py +0 -0
  183. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/parity/roi.py +0 -0
  184. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/parity/roi_extraction.py +0 -0
  185. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/parity/saved_analysis.py +0 -0
  186. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/photodiode.py +0 -0
  187. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/photodiode_classification.py +0 -0
  188. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/pixel_calibration.py +0 -0
  189. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/pixel_calibration_profiles.py +0 -0
  190. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/response_roi_extraction.py +0 -0
  191. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/roi.py +0 -0
  192. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/roi_extraction.py +0 -0
  193. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/roi_mask_cleanup.py +0 -0
  194. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/session.py +0 -0
  195. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/spatial.py +0 -0
  196. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/spatial_orientation.py +0 -0
  197. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/stimulus.py +0 -0
  198. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/synchronization.py +0 -0
  199. {twopy-0.3.2 → twopy-0.3.4}/src/twopy/typing_guards.py +0 -0
  200. {twopy-0.3.2 → twopy-0.3.4}/src/twopy.egg-info/dependency_links.txt +0 -0
  201. {twopy-0.3.2 → twopy-0.3.4}/src/twopy.egg-info/entry_points.txt +0 -0
  202. {twopy-0.3.2 → twopy-0.3.4}/src/twopy.egg-info/top_level.txt +0 -0
  203. {twopy-0.3.2 → twopy-0.3.4}/tests/test_api.py +0 -0
  204. {twopy-0.3.2 → twopy-0.3.4}/tests/test_background_subtraction.py +0 -0
  205. {twopy-0.3.2 → twopy-0.3.4}/tests/test_cache_inventory.py +0 -0
  206. {twopy-0.3.2 → twopy-0.3.4}/tests/test_config.py +0 -0
  207. {twopy-0.3.2 → twopy-0.3.4}/tests/test_conversion.py +0 -0
  208. {twopy-0.3.2 → twopy-0.3.4}/tests/test_converted.py +0 -0
  209. {twopy-0.3.2 → twopy-0.3.4}/tests/test_custom_workflows.py +0 -0
  210. {twopy-0.3.2 → twopy-0.3.4}/tests/test_database.py +0 -0
  211. {twopy-0.3.2 → twopy-0.3.4}/tests/test_dff.py +0 -0
  212. {twopy-0.3.2 → twopy-0.3.4}/tests/test_epoch_mapping.py +0 -0
  213. {twopy-0.3.2 → twopy-0.3.4}/tests/test_filenames.py +0 -0
  214. {twopy-0.3.2 → twopy-0.3.4}/tests/test_frame_ranges.py +0 -0
  215. {twopy-0.3.2 → twopy-0.3.4}/tests/test_function_inventory.py +0 -0
  216. {twopy-0.3.2 → twopy-0.3.4}/tests/test_hdf5_utils.py +0 -0
  217. {twopy-0.3.2 → twopy-0.3.4}/tests/test_inspection.py +0 -0
  218. {twopy-0.3.2 → twopy-0.3.4}/tests/test_kernels.py +0 -0
  219. {twopy-0.3.2 → twopy-0.3.4}/tests/test_load_workflow.py +0 -0
  220. {twopy-0.3.2 → twopy-0.3.4}/tests/test_matlab.py +0 -0
  221. {twopy-0.3.2 → twopy-0.3.4}/tests/test_motion.py +0 -0
  222. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_database_search.py +0 -0
  223. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_display.py +0 -0
  224. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_export.py +0 -0
  225. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_group_matching_responses.py +0 -0
  226. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_live_controller.py +0 -0
  227. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_load_controller.py +0 -0
  228. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_load_progress.py +0 -0
  229. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_load_tab.py +0 -0
  230. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_path_resolution.py +0 -0
  231. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_plot_data.py +0 -0
  232. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_processing_controls.py +0 -0
  233. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_response_map_display.py +0 -0
  234. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_response_workflow.py +0 -0
  235. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_roi_generation.py +0 -0
  236. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_roi_visibility.py +0 -0
  237. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_text.py +0 -0
  238. {twopy-0.3.2 → twopy-0.3.4}/tests/test_napari_timeline.py +0 -0
  239. {twopy-0.3.2 → twopy-0.3.4}/tests/test_parity.py +0 -0
  240. {twopy-0.3.2 → twopy-0.3.4}/tests/test_parity_psycho5.py +0 -0
  241. {twopy-0.3.2 → twopy-0.3.4}/tests/test_parity_roi_extraction.py +0 -0
  242. {twopy-0.3.2 → twopy-0.3.4}/tests/test_persistence.py +0 -0
  243. {twopy-0.3.2 → twopy-0.3.4}/tests/test_photodiode_classification.py +0 -0
  244. {twopy-0.3.2 → twopy-0.3.4}/tests/test_pixel_calibration.py +0 -0
  245. {twopy-0.3.2 → twopy-0.3.4}/tests/test_pixel_calibration_profiles.py +0 -0
  246. {twopy-0.3.2 → twopy-0.3.4}/tests/test_real_fixture.py +0 -0
  247. {twopy-0.3.2 → twopy-0.3.4}/tests/test_recording_timing.py +0 -0
  248. {twopy-0.3.2 → twopy-0.3.4}/tests/test_response_map_area.py +0 -0
  249. {twopy-0.3.2 → twopy-0.3.4}/tests/test_response_maps.py +0 -0
  250. {twopy-0.3.2 → twopy-0.3.4}/tests/test_response_processing.py +0 -0
  251. {twopy-0.3.2 → twopy-0.3.4}/tests/test_response_roi_extraction.py +0 -0
  252. {twopy-0.3.2 → twopy-0.3.4}/tests/test_response_window_options.py +0 -0
  253. {twopy-0.3.2 → twopy-0.3.4}/tests/test_responses.py +0 -0
  254. {twopy-0.3.2 → twopy-0.3.4}/tests/test_roi.py +0 -0
  255. {twopy-0.3.2 → twopy-0.3.4}/tests/test_roi_extraction.py +0 -0
  256. {twopy-0.3.2 → twopy-0.3.4}/tests/test_roi_mask_cleanup.py +0 -0
  257. {twopy-0.3.2 → twopy-0.3.4}/tests/test_saved_analysis.py +0 -0
  258. {twopy-0.3.2 → twopy-0.3.4}/tests/test_session.py +0 -0
  259. {twopy-0.3.2 → twopy-0.3.4}/tests/test_stimulus.py +0 -0
  260. {twopy-0.3.2 → twopy-0.3.4}/tests/test_synchronization.py +0 -0
  261. {twopy-0.3.2 → twopy-0.3.4}/tests/test_trials.py +0 -0
  262. {twopy-0.3.2 → twopy-0.3.4}/tests/test_workflow.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: twopy
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: Two-photon imaging analysis tool with a napari interface.
5
5
  Author-email: Gustavo Madeira Santana <fromweb1@gumadeiras.com>
6
6
  License-Expression: MIT
@@ -12,6 +12,7 @@ Requires-Dist: h5py<4,>=3.16
12
12
  Requires-Dist: matplotlib<4,>=3.10
13
13
  Requires-Dist: napari[all]<0.8,>=0.7
14
14
  Requires-Dist: numpy<3,>=2.3
15
+ Requires-Dist: packaging<27,>=26
15
16
  Requires-Dist: pre-commit<5,>=4.6
16
17
  Requires-Dist: qtpy<3,>=2.4
17
18
  Requires-Dist: pyyaml<7,>=6.0.3
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "twopy"
7
- version = "0.3.2"
7
+ version = "0.3.4"
8
8
  description = "Two-photon imaging analysis tool with a napari interface."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13,<3.14"
@@ -17,6 +17,7 @@ dependencies = [
17
17
  "matplotlib>=3.10,<4",
18
18
  "napari[all]>=0.7,<0.8",
19
19
  "numpy>=2.3,<3",
20
+ "packaging>=26,<27",
20
21
  "pre-commit>=4.6,<5",
21
22
  "qtpy>=2.4,<3",
22
23
  "pyyaml>=6.0.3,<7",
@@ -37,7 +38,7 @@ Repository = "https://github.com/gumadeiras/twopy"
37
38
  where = ["src"]
38
39
 
39
40
  [tool.setuptools.package-data]
40
- twopy = ["calibrations/*.csv", "config.example.yml"]
41
+ twopy = ["calibrations/*.csv", "config.example.yml", "napari/assets/*.icns", "napari/assets/*.png"]
41
42
 
42
43
  [tool.ruff]
43
44
  line-length = 88
@@ -0,0 +1,328 @@
1
+ """Top-level package for the twopy two-photon imaging analysis tool.
2
+
3
+ The package exposes project metadata and script-friendly public APIs.
4
+ Inputs: none.
5
+ Outputs: package constants and helper functions imported by users and scripts.
6
+ """
7
+
8
+ from importlib import import_module
9
+
10
+ _LAZY_EXPORTS = {
11
+ "__version__": ("twopy._version", "__version__"),
12
+ "DEFAULT_RESPONSE_POST_WINDOW_SECONDS": (
13
+ "twopy.analysis",
14
+ "DEFAULT_RESPONSE_POST_WINDOW_SECONDS",
15
+ ),
16
+ "DEFAULT_RESPONSE_PRE_WINDOW_SECONDS": (
17
+ "twopy.analysis",
18
+ "DEFAULT_RESPONSE_PRE_WINDOW_SECONDS",
19
+ ),
20
+ "AnalysisResponseComputation": ("twopy.analysis", "AnalysisResponseComputation"),
21
+ "AnalysisResponseRun": ("twopy.analysis", "AnalysisResponseRun"),
22
+ "BackgroundCorrectedRoiTraces": ("twopy.analysis", "BackgroundCorrectedRoiTraces"),
23
+ "BackgroundCorrectionMethod": ("twopy.analysis", "BackgroundCorrectionMethod"),
24
+ "CorrelationFilterOptions": ("twopy.analysis", "CorrelationFilterOptions"),
25
+ "DeltaFOverFBaselineMode": ("twopy.analysis", "DeltaFOverFBaselineMode"),
26
+ "DeltaFOverFFitMode": ("twopy.analysis", "DeltaFOverFFitMode"),
27
+ "DeltaFOverFOptions": ("twopy.analysis", "DeltaFOverFOptions"),
28
+ "EpochFrameWindow": ("twopy.analysis", "EpochFrameWindow"),
29
+ "EpochResponseMap": ("twopy.analysis", "EpochResponseMap"),
30
+ "FrameWindow": ("twopy.analysis", "FrameWindow"),
31
+ "GroupedRoiResponses": ("twopy.analysis", "GroupedRoiResponses"),
32
+ "GroupedRoiResponseSummary": ("twopy.analysis", "GroupedRoiResponseSummary"),
33
+ "Hemisphere": ("twopy.analysis", "Hemisphere"),
34
+ "KernelFitMethod": ("twopy.analysis", "KernelFitMethod"),
35
+ "KernelStimulusModality": ("twopy.analysis", "KernelStimulusModality"),
36
+ "LoadedAnalysisOutputs": ("twopy.analysis", "LoadedAnalysisOutputs"),
37
+ "LowPassFilterOptions": ("twopy.analysis", "LowPassFilterOptions"),
38
+ "ManualFovGroupRow": ("twopy.analysis", "ManualFovGroupRow"),
39
+ "ManualRoiMatchGroup": ("twopy.analysis", "ManualRoiMatchGroup"),
40
+ "ManualRoiMatchRow": ("twopy.analysis", "ManualRoiMatchRow"),
41
+ "ManualRoiMatchStatus": ("twopy.analysis", "ManualRoiMatchStatus"),
42
+ "RecordingKernelFit": ("twopy.analysis", "RecordingKernelFit"),
43
+ "RecordingTiming": ("twopy.analysis", "RecordingTiming"),
44
+ "ResponseMapData": ("twopy.analysis", "ResponseMapData"),
45
+ "ResponseMapMode": ("twopy.analysis", "ResponseMapMode"),
46
+ "ResponseMapOptions": ("twopy.analysis", "ResponseMapOptions"),
47
+ "ResponseProcessingOptions": ("twopy.analysis", "ResponseProcessingOptions"),
48
+ "RoiCorrelationScores": ("twopy.analysis", "RoiCorrelationScores"),
49
+ "RoiDeltaFOverF": ("twopy.analysis", "RoiDeltaFOverF"),
50
+ "RoiResponseSummary": ("twopy.analysis", "RoiResponseSummary"),
51
+ "RoiResponseTrial": ("twopy.analysis", "RoiResponseTrial"),
52
+ "SmoothingOptions": ("twopy.analysis", "SmoothingOptions"),
53
+ "StimulusKernelOptions": ("twopy.analysis", "StimulusKernelOptions"),
54
+ "TimingSource": ("twopy.analysis", "TimingSource"),
55
+ "WindowedRoiResponse": ("twopy.analysis", "WindowedRoiResponse"),
56
+ "add_manual_roi_match_group": ("twopy.analysis", "add_manual_roi_match_group"),
57
+ "analyze_recording_responses": ("twopy.analysis", "analyze_recording_responses"),
58
+ "append_manual_roi_match_rows": ("twopy.analysis", "append_manual_roi_match_rows"),
59
+ "apply_motion_artifact_mask_to_delta_f_over_f": (
60
+ "twopy.analysis",
61
+ "apply_motion_artifact_mask_to_delta_f_over_f",
62
+ ),
63
+ "compute_recording_response_maps": (
64
+ "twopy.analysis",
65
+ "compute_recording_response_maps",
66
+ ),
67
+ "compute_recording_responses": ("twopy.analysis", "compute_recording_responses"),
68
+ "compute_roi_delta_f_over_f": ("twopy.analysis", "compute_roi_delta_f_over_f"),
69
+ "default_baseline_epoch_number": (
70
+ "twopy.analysis",
71
+ "default_baseline_epoch_number",
72
+ ),
73
+ "default_kernel_stimulus_column": (
74
+ "twopy.analysis",
75
+ "default_kernel_stimulus_column",
76
+ ),
77
+ "default_recording_baseline_epoch_number": (
78
+ "twopy.analysis",
79
+ "default_recording_baseline_epoch_number",
80
+ ),
81
+ "extract_background_corrected_roi_traces": (
82
+ "twopy.analysis",
83
+ "extract_background_corrected_roi_traces",
84
+ ),
85
+ "finite_mean_and_sem": ("twopy.analysis", "finite_mean_and_sem"),
86
+ "fit_recording_stimulus_kernels": (
87
+ "twopy.analysis",
88
+ "fit_recording_stimulus_kernels",
89
+ ),
90
+ "fit_stimulus_kernel": ("twopy.analysis", "fit_stimulus_kernel"),
91
+ "group_delta_f_over_f_by_epoch": (
92
+ "twopy.analysis",
93
+ "group_delta_f_over_f_by_epoch",
94
+ ),
95
+ "is_baseline_epoch_name": ("twopy.analysis", "is_baseline_epoch_name"),
96
+ "load_analysis_outputs": ("twopy.analysis", "load_analysis_outputs"),
97
+ "load_manual_fov_group_rows": ("twopy.analysis", "load_manual_fov_group_rows"),
98
+ "load_manual_roi_match_rows": ("twopy.analysis", "load_manual_roi_match_rows"),
99
+ "load_response_map_data": ("twopy.analysis", "load_response_map_data"),
100
+ "make_frame_windows": ("twopy.analysis", "make_frame_windows"),
101
+ "make_manual_fov_group_rows": ("twopy.analysis", "make_manual_fov_group_rows"),
102
+ "make_manual_roi_match_rows": ("twopy.analysis", "make_manual_roi_match_rows"),
103
+ "matched_manual_roi_groups": ("twopy.analysis", "matched_manual_roi_groups"),
104
+ "next_group_cell_id": ("twopy.analysis", "next_group_cell_id"),
105
+ "no_baseline_epoch_frame_windows": (
106
+ "twopy.analysis",
107
+ "no_baseline_epoch_frame_windows",
108
+ ),
109
+ "remove_manual_roi_match_group": (
110
+ "twopy.analysis",
111
+ "remove_manual_roi_match_group",
112
+ ),
113
+ "replace_manual_roi_match_group": (
114
+ "twopy.analysis",
115
+ "replace_manual_roi_match_group",
116
+ ),
117
+ "resolve_baseline_frame_windows": (
118
+ "twopy.analysis",
119
+ "resolve_baseline_frame_windows",
120
+ ),
121
+ "resolve_recording_timing": ("twopy.analysis", "resolve_recording_timing"),
122
+ "save_analysis_outputs": ("twopy.analysis", "save_analysis_outputs"),
123
+ "save_manual_fov_group_rows": ("twopy.analysis", "save_manual_fov_group_rows"),
124
+ "save_manual_roi_match_rows": ("twopy.analysis", "save_manual_roi_match_rows"),
125
+ "save_response_map_data": ("twopy.analysis", "save_response_map_data"),
126
+ "select_baseline_frame_windows": (
127
+ "twopy.analysis",
128
+ "select_baseline_frame_windows",
129
+ ),
130
+ "split_traces_by_frame_windows": (
131
+ "twopy.analysis",
132
+ "split_traces_by_frame_windows",
133
+ ),
134
+ "summarize_epoch_roi_responses": (
135
+ "twopy.analysis",
136
+ "summarize_epoch_roi_responses",
137
+ ),
138
+ "summarize_grouped_responses": ("twopy.analysis", "summarize_grouped_responses"),
139
+ "validate_grouped_roi_responses": (
140
+ "twopy.analysis",
141
+ "validate_grouped_roi_responses",
142
+ ),
143
+ "write_response_summary_grouped_csv": (
144
+ "twopy.analysis",
145
+ "write_response_summary_grouped_csv",
146
+ ),
147
+ "write_response_summary_trials_csv": (
148
+ "twopy.analysis",
149
+ "write_response_summary_trials_csv",
150
+ ),
151
+ "find_recordings": ("twopy.api", "find_recordings"),
152
+ "convert_recording_to_twopy": ("twopy.conversion", "convert_recording_to_twopy"),
153
+ "load_source_conversion_inputs": (
154
+ "twopy.conversion",
155
+ "load_source_conversion_inputs",
156
+ ),
157
+ "load_converted_recording": ("twopy.converted", "load_converted_recording"),
158
+ "recording_frame_rate_hz": ("twopy.converted", "recording_frame_rate_hz"),
159
+ "recording_hemisphere": ("twopy.converted", "recording_hemisphere"),
160
+ "ClassifiedPhotodiodeEvent": (
161
+ "twopy.photodiode_classification",
162
+ "ClassifiedPhotodiodeEvent",
163
+ ),
164
+ "ClassifiedStimulusTiming": (
165
+ "twopy.photodiode_classification",
166
+ "ClassifiedStimulusTiming",
167
+ ),
168
+ "ClassifiedStimulusWindow": (
169
+ "twopy.photodiode_classification",
170
+ "ClassifiedStimulusWindow",
171
+ ),
172
+ "PhotodiodeDurationClass": (
173
+ "twopy.photodiode_classification",
174
+ "PhotodiodeDurationClass",
175
+ ),
176
+ "PhotodiodeEventType": ("twopy.photodiode_classification", "PhotodiodeEventType"),
177
+ "classify_recording_photodiode_events": (
178
+ "twopy.photodiode_classification",
179
+ "classify_recording_photodiode_events",
180
+ ),
181
+ "DEFAULT_PIXEL_CALIBRATION_PATH": (
182
+ "twopy.pixel_calibration",
183
+ "DEFAULT_PIXEL_CALIBRATION_PATH",
184
+ ),
185
+ "PixelCalibrationResolution": (
186
+ "twopy.pixel_calibration",
187
+ "PixelCalibrationResolution",
188
+ ),
189
+ "PixelCalibrationResolutionMethod": (
190
+ "twopy.pixel_calibration",
191
+ "PixelCalibrationResolutionMethod",
192
+ ),
193
+ "PixelCalibrationRow": ("twopy.pixel_calibration", "PixelCalibrationRow"),
194
+ "load_pixel_calibrations": ("twopy.pixel_calibration", "load_pixel_calibrations"),
195
+ "resolve_pixel_size_um": ("twopy.pixel_calibration", "resolve_pixel_size_um"),
196
+ "DEFAULT_PIXEL_CALIBRATION_PROFILE_PATH": (
197
+ "twopy.pixel_calibration_profiles",
198
+ "DEFAULT_PIXEL_CALIBRATION_PROFILE_PATH",
199
+ ),
200
+ "PixelCalibrationGroup": (
201
+ "twopy.pixel_calibration_profiles",
202
+ "PixelCalibrationGroup",
203
+ ),
204
+ "PixelCalibrationProfile": (
205
+ "twopy.pixel_calibration_profiles",
206
+ "PixelCalibrationProfile",
207
+ ),
208
+ "PixelCalibrationProfileMapping": (
209
+ "twopy.pixel_calibration_profiles",
210
+ "PixelCalibrationProfileMapping",
211
+ ),
212
+ "PixelCalibrationProfileSource": (
213
+ "twopy.pixel_calibration_profiles",
214
+ "PixelCalibrationProfileSource",
215
+ ),
216
+ "load_pixel_calibration_profile_mappings": (
217
+ "twopy.pixel_calibration_profiles",
218
+ "load_pixel_calibration_profile_mappings",
219
+ ),
220
+ "resolve_pixel_calibration_profile": (
221
+ "twopy.pixel_calibration_profiles",
222
+ "resolve_pixel_calibration_profile",
223
+ ),
224
+ "select_pixel_calibration_group": (
225
+ "twopy.pixel_calibration_profiles",
226
+ "select_pixel_calibration_group",
227
+ ),
228
+ "ResponseNormalization": ("twopy.response_roi_extraction", "ResponseNormalization"),
229
+ "ResponsePolarity": ("twopy.response_roi_extraction", "ResponsePolarity"),
230
+ "ResponseStatistic": ("twopy.response_roi_extraction", "ResponseStatistic"),
231
+ "ResponseWatershedExtraction": (
232
+ "twopy.response_roi_extraction",
233
+ "ResponseWatershedExtraction",
234
+ ),
235
+ "ResponseWatershedScoreImages": (
236
+ "twopy.response_roi_extraction",
237
+ "ResponseWatershedScoreImages",
238
+ ),
239
+ "extract_response_watershed_rois": (
240
+ "twopy.response_roi_extraction",
241
+ "extract_response_watershed_rois",
242
+ ),
243
+ "response_watershed_roi_set": (
244
+ "twopy.response_roi_extraction",
245
+ "response_watershed_roi_set",
246
+ ),
247
+ "RoiSet": ("twopy.roi", "RoiSet"),
248
+ "RoiTraces": ("twopy.roi", "RoiTraces"),
249
+ "extract_roi_traces": ("twopy.roi", "extract_roi_traces"),
250
+ "load_roi_set": ("twopy.roi", "load_roi_set"),
251
+ "make_roi_set": ("twopy.roi", "make_roi_set"),
252
+ "make_roi_set_from_label_image": ("twopy.roi", "make_roi_set_from_label_image"),
253
+ "roi_set_to_label_image": ("twopy.roi", "roi_set_to_label_image"),
254
+ "save_roi_set": ("twopy.roi", "save_roi_set"),
255
+ "RoiExtractionConfig": ("twopy.roi_extraction", "RoiExtractionConfig"),
256
+ "RoiExtractionMethod": ("twopy.roi_extraction", "RoiExtractionMethod"),
257
+ "extract_rois_from_image": ("twopy.roi_extraction", "extract_rois_from_image"),
258
+ "grid_roi_set": ("twopy.roi_extraction", "grid_roi_set"),
259
+ "grid_roi_set_microns": ("twopy.roi_extraction", "grid_roi_set_microns"),
260
+ "grid_size_pixels_from_microns": (
261
+ "twopy.roi_extraction",
262
+ "grid_size_pixels_from_microns",
263
+ ),
264
+ "watershed_roi_set": ("twopy.roi_extraction", "watershed_roi_set"),
265
+ "SpatialCrop": ("twopy.spatial", "SpatialCrop"),
266
+ "SpatialDomain": ("twopy.spatial", "SpatialDomain"),
267
+ "full_frame_crop": ("twopy.spatial", "full_frame_crop"),
268
+ "StimulusSpecificColumnMapping": (
269
+ "twopy.stimulus",
270
+ "StimulusSpecificColumnMapping",
271
+ ),
272
+ "map_stimulus_specific_column": ("twopy.stimulus", "map_stimulus_specific_column"),
273
+ "stimulus_epoch_names_by_number": (
274
+ "twopy.stimulus",
275
+ "stimulus_epoch_names_by_number",
276
+ ),
277
+ "AlignedPhotodiodeEvent": ("twopy.synchronization", "AlignedPhotodiodeEvent"),
278
+ "PhotodiodeAlignment": ("twopy.synchronization", "PhotodiodeAlignment"),
279
+ "PhotodiodeEvent": ("twopy.synchronization", "PhotodiodeEvent"),
280
+ "PhotodiodeEventSet": ("twopy.synchronization", "PhotodiodeEventSet"),
281
+ "detect_photodiode_events": ("twopy.synchronization", "detect_photodiode_events"),
282
+ "detect_recording_photodiode_events": (
283
+ "twopy.synchronization",
284
+ "detect_recording_photodiode_events",
285
+ ),
286
+ "pair_photodiode_events_to_imaging_frames": (
287
+ "twopy.synchronization",
288
+ "pair_photodiode_events_to_imaging_frames",
289
+ ),
290
+ }
291
+
292
+ __all__ = list(_LAZY_EXPORTS)
293
+
294
+
295
+ def __getattr__(name: str) -> object:
296
+ """Load public API names only when callers ask for them.
297
+
298
+ Args:
299
+ name: Public attribute requested from ``twopy``.
300
+
301
+ Returns:
302
+ The exported object from its owning module.
303
+
304
+ The napari launcher imports this package before it can import
305
+ ``twopy.napari``. Delaying the scientific API imports keeps application
306
+ startup from paying for SciPy and HDF5 modules before the GUI needs them.
307
+ """
308
+ try:
309
+ module_name, attribute_name = _LAZY_EXPORTS[name]
310
+ except KeyError as error:
311
+ msg = f"module {__name__!r} has no attribute {name!r}"
312
+ raise AttributeError(msg) from error
313
+ module = import_module(module_name)
314
+ value = getattr(module, attribute_name)
315
+ globals()[name] = value
316
+ return value
317
+
318
+
319
+ def __dir__() -> list[str]:
320
+ """Return module attributes plus lazy public API names.
321
+
322
+ Args:
323
+ None.
324
+
325
+ Returns:
326
+ Sorted module names for notebooks, shells, and documentation tools.
327
+ """
328
+ return sorted(set(globals()) | set(__all__))