ephys-link 1.0.0rc1__tar.gz → 1.0.6a0__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 (44) hide show
  1. ephys_link-1.0.6a0/.gitignore +295 -0
  2. ephys_link-1.0.6a0/PKG-INFO +158 -0
  3. {ephys-link-1.0.0rc1 → ephys_link-1.0.6a0}/README.md +5 -4
  4. ephys_link-1.0.6a0/pyproject.toml +104 -0
  5. ephys_link-1.0.6a0/src/ephys_link/__about__.py +1 -0
  6. {ephys-link-1.0.0rc1 → ephys_link-1.0.6a0}/src/ephys_link/__main__.py +3 -6
  7. {ephys-link-1.0.0rc1 → ephys_link-1.0.6a0}/src/ephys_link/common.py +22 -19
  8. {ephys-link-1.0.0rc1 → ephys_link-1.0.6a0}/src/ephys_link/gui.py +20 -37
  9. {ephys-link-1.0.0rc1 → ephys_link-1.0.6a0}/src/ephys_link/platform_handler.py +46 -50
  10. ephys_link-1.0.6a0/src/ephys_link/platforms/__init__.py +0 -0
  11. {ephys-link-1.0.0rc1 → ephys_link-1.0.6a0}/src/ephys_link/platforms/new_scale_handler.py +24 -36
  12. {ephys-link-1.0.0rc1 → ephys_link-1.0.6a0}/src/ephys_link/platforms/new_scale_manipulator.py +16 -31
  13. {ephys-link-1.0.0rc1 → ephys_link-1.0.6a0}/src/ephys_link/platforms/new_scale_pathfinder_handler.py +36 -32
  14. {ephys-link-1.0.0rc1 → ephys_link-1.0.6a0}/src/ephys_link/platforms/sensapex_handler.py +26 -39
  15. {ephys-link-1.0.0rc1 → ephys_link-1.0.6a0}/src/ephys_link/platforms/sensapex_manipulator.py +16 -26
  16. {ephys-link-1.0.0rc1 → ephys_link-1.0.6a0}/src/ephys_link/platforms/ump3_handler.py +26 -38
  17. {ephys-link-1.0.0rc1 → ephys_link-1.0.6a0}/src/ephys_link/platforms/ump3_manipulator.py +16 -26
  18. {ephys-link-1.0.0rc1 → ephys_link-1.0.6a0}/src/ephys_link/server.py +32 -30
  19. ephys_link-1.0.6a0/tests/__init__.py +3 -0
  20. ephys-link-1.0.0rc1/MANIFEST.in +0 -1
  21. ephys-link-1.0.0rc1/PKG-INFO +0 -830
  22. ephys-link-1.0.0rc1/pyproject.toml +0 -55
  23. ephys-link-1.0.0rc1/scripts/new_scale_move.py +0 -63
  24. ephys-link-1.0.0rc1/scripts/probe_crash_test.py +0 -85
  25. ephys-link-1.0.0rc1/scripts/read_to_file.py +0 -143
  26. ephys-link-1.0.0rc1/setup.cfg +0 -4
  27. ephys-link-1.0.0rc1/src/ephys_link.egg-info/SOURCES.txt +0 -35
  28. ephys-link-1.0.0rc1/tests/__init__.py +0 -1
  29. ephys-link-1.0.0rc1/tests/calibration_test.py +0 -82
  30. ephys-link-1.0.0rc1/tests/can_write_test.py +0 -81
  31. ephys-link-1.0.0rc1/tests/drive_to_depth_test.py +0 -104
  32. ephys-link-1.0.0rc1/tests/get_manipulators_test.py +0 -32
  33. ephys-link-1.0.0rc1/tests/get_pos_test.py +0 -48
  34. ephys-link-1.0.0rc1/tests/inside_brain_test.py +0 -86
  35. ephys-link-1.0.0rc1/tests/move_test.py +0 -238
  36. ephys-link-1.0.0rc1/tests/register_manipulator_test.py +0 -47
  37. ephys-link-1.0.0rc1/tests/stop_test.py +0 -127
  38. {ephys-link-1.0.0rc1 → ephys_link-1.0.6a0}/LICENSE +0 -0
  39. {ephys-link-1.0.0rc1 → ephys_link-1.0.6a0}/src/ephys_link/__init__.py +0 -0
  40. {ephys-link-1.0.0rc1 → ephys_link-1.0.6a0}/src/ephys_link/platform_manipulator.py +0 -0
  41. {ephys-link-1.0.0rc1 → ephys_link-1.0.6a0}/src/ephys_link/resources/CP210xManufacturing.dll +0 -0
  42. {ephys-link-1.0.0rc1 → ephys_link-1.0.6a0}/src/ephys_link/resources/NstMotorCtrl.dll +0 -0
  43. {ephys-link-1.0.0rc1 → ephys_link-1.0.6a0}/src/ephys_link/resources/SiUSBXp.dll +0 -0
  44. {ephys-link-1.0.0rc1 → ephys_link-1.0.6a0}/src/ephys_link/resources/libum.dll +0 -0
@@ -0,0 +1,295 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+ !libum.so
9
+
10
+ # Distribution / packaging
11
+ .Python
12
+ build/
13
+ develop-eggs/
14
+ dist/
15
+ downloads/
16
+ eggs/
17
+ .eggs/
18
+ lib/
19
+ lib64/
20
+ parts/
21
+ sdist/
22
+ var/
23
+ wheels/
24
+ pip-wheel-metadata/
25
+ share/python-wheels/
26
+ *.egg-info/
27
+ .installed.cfg
28
+ *.egg
29
+ MANIFEST
30
+
31
+ # PyInstaller
32
+ # Usually these files are written by a python script from a template
33
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
34
+ *.manifest
35
+ *.spec
36
+
37
+ # Installer logs
38
+ pip-log.txt
39
+ pip-delete-this-directory.txt
40
+
41
+ # Unit test / coverage reports
42
+ htmlcov/
43
+ .tox/
44
+ .nox/
45
+ .coverage
46
+ .coverage.*
47
+ .cache
48
+ nosetests.xml
49
+ coverage.xml
50
+ *.cover
51
+ *.py,cover
52
+ .hypothesis/
53
+ .pytest_cache/
54
+
55
+ # Translations
56
+ *.mo
57
+ *.pot
58
+
59
+ # Django stuff:
60
+ *.log
61
+ local_settings.py
62
+ db.sqlite3
63
+ db.sqlite3-journal
64
+
65
+ # Flask stuff:
66
+ instance/
67
+ .webassets-cache
68
+
69
+ # Scrapy stuff:
70
+ .scrapy
71
+
72
+ # Sphinx documentation
73
+ docs/_build/
74
+
75
+ # PyBuilder
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ .python-version
87
+
88
+ # pipenv
89
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
90
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
91
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
92
+ # install all needed dependencies.
93
+ #Pipfile.lock
94
+
95
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
96
+ __pypackages__/
97
+
98
+ # Celery stuff
99
+ celerybeat-schedule
100
+ celerybeat.pid
101
+
102
+ # SageMath parsed files
103
+ *.sage.py
104
+
105
+ # Environments
106
+ .env
107
+ .venv
108
+ env/
109
+ venv/
110
+ ENV/
111
+ env.bak/
112
+ venv.bak/
113
+
114
+ # Spyder project settings
115
+ .spyderproject
116
+ .spyproject
117
+
118
+ # Rope project settings
119
+ .ropeproject
120
+
121
+ # mkdocs documentation
122
+ /site
123
+
124
+ # mypy
125
+ .mypy_cache/
126
+ .dmypy.json
127
+ dmypy.json
128
+
129
+ # Pyre type checker
130
+ .pyre/
131
+
132
+
133
+
134
+ # Created by https://www.toptal.com/developers/gitignore/api/python,pycharm
135
+ # Edit at https://www.toptal.com/developers/gitignore?templates=python,pycharm
136
+
137
+ ### PyCharm ###
138
+ # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
139
+ # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
140
+
141
+ # User-specific stuff
142
+ .idea/**/workspace.xml
143
+ .idea/**/tasks.xml
144
+ .idea/**/usage.statistics.xml
145
+ .idea/**/dictionaries
146
+ .idea/**/shelf
147
+
148
+ # AWS User-specific
149
+ .idea/**/aws.xml
150
+
151
+ # Generated files
152
+ .idea/**/contentModel.xml
153
+
154
+ # Sensitive or high-churn files
155
+ .idea/**/dataSources/
156
+ .idea/**/dataSources.ids
157
+ .idea/**/dataSources.local.xml
158
+ .idea/**/sqlDataSources.xml
159
+ .idea/**/dynamic.xml
160
+ .idea/**/uiDesigner.xml
161
+ .idea/**/dbnavigator.xml
162
+
163
+ # Gradle
164
+ .idea/**/gradle.xml
165
+ .idea/**/libraries
166
+
167
+ # Gradle and Maven with auto-import
168
+ # When using Gradle or Maven with auto-import, you should exclude module files,
169
+ # since they will be recreated, and may cause churn. Uncomment if using
170
+ # auto-import.
171
+ # .idea/artifacts
172
+ # .idea/compiler.xml
173
+ # .idea/jarRepositories.xml
174
+ # .idea/modules.xml
175
+ # .idea/*.iml
176
+ # .idea/modules
177
+ # *.iml
178
+ # *.ipr
179
+
180
+ # CMake
181
+ cmake-build-*/
182
+
183
+ # Mongo Explorer plugin
184
+ .idea/**/mongoSettings.xml
185
+
186
+ # File-based project format
187
+ *.iws
188
+
189
+ # IntelliJ
190
+ out/
191
+
192
+ # mpeltonen/sbt-idea plugin
193
+ .idea_modules/
194
+
195
+ # JIRA plugin
196
+ atlassian-ide-plugin.xml
197
+
198
+ # Cursive Clojure plugin
199
+ .idea/replstate.xml
200
+
201
+ # SonarLint plugin
202
+ .idea/sonarlint/
203
+
204
+ # Crashlytics plugin (for Android Studio and IntelliJ)
205
+ com_crashlytics_export_strings.xml
206
+ crashlytics.properties
207
+ crashlytics-build.properties
208
+ fabric.properties
209
+
210
+ # Editor-based Rest Client
211
+ .idea/httpRequests
212
+
213
+ # Android studio 3.1+ serialized cache file
214
+ .idea/caches/build_file_checksums.ser
215
+
216
+ ### PyCharm Patch ###
217
+ # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
218
+
219
+ # *.iml
220
+ # modules.xml
221
+ # .idea/misc.xml
222
+ # *.ipr
223
+
224
+ # Sonarlint plugin
225
+ # https://plugins.jetbrains.com/plugin/7973-sonarlint
226
+ .idea/**/sonarlint/
227
+
228
+ # SonarQube Plugin
229
+ # https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
230
+ .idea/**/sonarIssues.xml
231
+
232
+ # Markdown Navigator plugin
233
+ # https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
234
+ .idea/**/markdown-navigator.xml
235
+ .idea/**/markdown-navigator-enh.xml
236
+ .idea/**/markdown-navigator/
237
+
238
+ # Cache file creation bug
239
+ # See https://youtrack.jetbrains.com/issue/JBR-2257
240
+ .idea/$CACHE_FILE$
241
+
242
+ # CodeStream plugin
243
+ # https://plugins.jetbrains.com/plugin/12206-codestream
244
+ .idea/codestream.xml
245
+
246
+ # Azure Toolkit for IntelliJ plugin
247
+ # https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
248
+ .idea/**/azureSettings.xml
249
+
250
+
251
+ # PyBuilder
252
+ .pybuilder/
253
+
254
+
255
+ # pyenv
256
+ # For a library or package, you might want to ignore these files since the code is
257
+ # intended to run in multiple environments; otherwise, check them in:
258
+ # .python-version
259
+
260
+ # pipenv
261
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
262
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
263
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
264
+ # install all needed dependencies.
265
+ #Pipfile.lock
266
+
267
+ # poetry
268
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
269
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
270
+ # commonly ignored for libraries.
271
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
272
+ #poetry.lock
273
+
274
+ # pdm
275
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
276
+ #pdm.lock
277
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
278
+ # in version control.
279
+ # https://pdm.fming.dev/#use-with-ide
280
+ .pdm.toml
281
+
282
+ # pytype static type analyzer
283
+ .pytype/
284
+
285
+ # Cython debug symbols
286
+ cython_debug/
287
+
288
+ # PyCharm
289
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
290
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
291
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
292
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
293
+ #.idea/
294
+
295
+ # End of https://www.toptal.com/developers/gitignore/api/python,pycharm
@@ -0,0 +1,158 @@
1
+ Metadata-Version: 2.1
2
+ Name: ephys-link
3
+ Version: 1.0.6a0
4
+ Summary: A Python Socket.IO server that allows any Socket.IO-compliant application to communicate with manipulators used in electrophysiology experiments.
5
+ Project-URL: Documentation, https://virtualbrainlab.org/ephys_link/installation_and_use.html
6
+ Project-URL: Issues, https://github.com/VirtualBrainLab/ephys-link/issues
7
+ Project-URL: Source, https://github.com/VirtualBrainLab/ephys-link
8
+ Author-email: Kenneth Yang <kjy5@uw.edu>
9
+ Maintainer-email: Kenneth Yang <kjy5@uw.edu>
10
+ License-Expression: GPL-3.0-only
11
+ License-File: LICENSE
12
+ Keywords: electrophysiology,ephys,manipulator,neuroscience,neurotech,new-scale,sensapex,socket-io,virtualbrainlab
13
+ Classifier: Intended Audience :: End Users/Desktop
14
+ Classifier: Intended Audience :: Healthcare Industry
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.8
21
+ Classifier: Programming Language :: Python :: 3.9
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: Implementation :: CPython
26
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
27
+ Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
28
+ Requires-Python: <3.13,>=3.8
29
+ Requires-Dist: aiohttp==3.9.1
30
+ Requires-Dist: pyserial==3.5
31
+ Requires-Dist: python-socketio==5.10.0
32
+ Requires-Dist: pythonnet==3.0.3
33
+ Requires-Dist: sensapex==1.400.0
34
+ Requires-Dist: wheel==0.42.0
35
+ Description-Content-Type: text/markdown
36
+
37
+ # Electrophysiology Manipulator Link
38
+
39
+ [![PyPI version](https://badge.fury.io/py/ephys-link.svg)](https://badge.fury.io/py/ephys-link)
40
+ [![CodeQL](https://github.com/VirtualBrainLab/ephys-link/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/VirtualBrainLab/ephys-link/actions/workflows/codeql-analysis.yml)
41
+ [![Dependency Review](https://github.com/VirtualBrainLab/ephys-link/actions/workflows/dependency-review.yml/badge.svg)](https://github.com/VirtualBrainLab/ephys-link/actions/workflows/dependency-review.yml)
42
+ [![Hatch project](https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg)](https://github.com/pypa/hatch)
43
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
44
+
45
+ <img width="100%" src="https://github.com/VirtualBrainLab/ephys-link/assets/82800265/c89e433c-2ce0-4f27-aa9d-66f89c59c979" alt="Manipulator and probe in pinpoint moving in sync">
46
+
47
+ The [Electrophysiology Manipulator Link](https://github.com/VirtualBrainLab/ephys-link)
48
+ (or Ephys Link for short) is a Python [Socket.IO](https://socket.io/docs/v4/#what-socketio-is) server that allows any
49
+ Socket.IO-compliant application (such
50
+ as [Pinpoint](https://github.com/VirtualBrainLab/Pinpoint))
51
+ to communicate with manipulators used in electrophysiology experiments.
52
+
53
+ Currently, Ephys Link only supports Sensapex uMp-4 and uMp-3 Micromanipulators and New Scale 3-axis
54
+ manipulators. However, this platform is designed to be extensible to other
55
+ manipulators and more may be added in the future.
56
+
57
+ For more information regarding the server's implementation and how the code is organized, see
58
+ the [package's development documentation](https://virtualbrainlab.org/ephys_link/development.html).
59
+
60
+ For detailed descriptions of the server's API, see
61
+ the [API reference](https://virtualbrainlab.org/api_reference_ephys_link.html).
62
+
63
+ # Installation
64
+
65
+ ## Prerequisites
66
+
67
+ 1. [Python ≥ 3.8, < 3.13](https://www.python.org/downloads/release/python-3116/)
68
+ 1. Python 3.12+ requires the latest version
69
+ of [Microsoft Visual C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/) (MSVC v143+) to
70
+ be installed.
71
+ 2. An **x86 Windows PC is required** to run the server.
72
+ 3. For Sensapex devices, the controller unit must be connected via an ethernet
73
+ cable and powered. A USB-to-ethernet adapter is acceptable. For New Scale manipulators,
74
+ the controller unit must be connected via USB and be powered by a 6V power
75
+ supply.
76
+ 4. To use the emergency stop feature, ensure an Arduino with
77
+ the [StopSignal](https://github.com/VirtualBrainLab/StopSignal) sketch is
78
+ connected to the computer. Follow the instructions on that repo for how to
79
+ set up the Arduino.
80
+
81
+ > ### Using a Python virtual environment is encouraged.
82
+ >
83
+ > Create a virtual environment by running `python -m venv ephys_link`
84
+ >
85
+ > Activate the environment by running `.\ephys_link\scripts\activate`
86
+ >
87
+ > A virtual environment helps to isolate installed packages from other packages on your computer and ensures a clean
88
+ > installation of Ephys Link
89
+
90
+ **NOTE:** Ephys Link is an HTTP server without cross-origin support. The server
91
+ is currently designed to interface with local/desktop instances of Pinpoint. It
92
+ will not work with the web browser versions of Pinpoint at this time.
93
+
94
+ ## Install for use
95
+
96
+ Run the following command to install the server:
97
+
98
+ ```bash
99
+ pip install ephys-link
100
+ ```
101
+
102
+ Update the server like any other Python package:
103
+
104
+ ```bash
105
+ pip install --upgrade ephys-link
106
+ ```
107
+
108
+ ## Install for development
109
+
110
+ 1. Clone the repository.
111
+ 2. Run the following command in the root directory of the repository to install the package along with development
112
+ tools:
113
+
114
+ ```bash
115
+ pip install -e .[dev]
116
+ ```
117
+
118
+ # Usage
119
+
120
+ Run the following commands in a terminal to start the server for the desired manipulator platform:
121
+
122
+ | Manipulator Platform | Command |
123
+ |--------------------------------------|--------------------------------------|
124
+ | Sensapex uMp-4 | `ephys-link` |
125
+ | Sensapex uMp-3 | `ephys-link -t ump3` |
126
+ | New Scale | `ephys-link -t new_scale` |
127
+ | New Scale via Pathfinder HTTP server | `ephys-link -t new_scale_pathfinder` |
128
+
129
+ There are a couple additional aliases for the Ephys Link executable: `ephys_link` and `el`.
130
+
131
+ By default, the server will broadcast with its local IP address on port 8081.
132
+ **Copy this information into Pinpoint to connect**.
133
+
134
+ For example, if the server is running on the same computer that Pinpoint is, use
135
+
136
+ - Server: `localhost`
137
+ - Port: `8081`
138
+
139
+ # Documentation and More Information
140
+
141
+ Complete documentation including API usage and development installation can be
142
+ found on the [Virtual Brain Lab Documentation page][docs] for Ephys Link.
143
+
144
+ # Citing
145
+
146
+ If this project is used as part of a research project you should cite
147
+ the [Pinpoint repository][Pinpoint]. Please email
148
+ Dan ([dbirman@uw.edu](mailto:dbirman@uw.edu)) if you have questions.
149
+
150
+ Please reach out to Kenneth ([kjy5@uw.edu](mailto:kjy5@uw.edu)) for questions
151
+ about the Electrophysiology Manipulator Link server. Bugs may be reported
152
+ through the issues tab.
153
+
154
+ [Pinpoint]: https://github.com/VirtualBrainLab/Pinpoint
155
+
156
+ [StopSignal]: https://github.com/VirtualBrainLab/StopSignal
157
+
158
+ [docs]: https://virtualbrainlab.org/ephys_link/installation_and_use.html
@@ -3,7 +3,8 @@
3
3
  [![PyPI version](https://badge.fury.io/py/ephys-link.svg)](https://badge.fury.io/py/ephys-link)
4
4
  [![CodeQL](https://github.com/VirtualBrainLab/ephys-link/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/VirtualBrainLab/ephys-link/actions/workflows/codeql-analysis.yml)
5
5
  [![Dependency Review](https://github.com/VirtualBrainLab/ephys-link/actions/workflows/dependency-review.yml/badge.svg)](https://github.com/VirtualBrainLab/ephys-link/actions/workflows/dependency-review.yml)
6
- [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
6
+ [![Hatch project](https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg)](https://github.com/pypa/hatch)
7
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
7
8
 
8
9
  <img width="100%" src="https://github.com/VirtualBrainLab/ephys-link/assets/82800265/c89e433c-2ce0-4f27-aa9d-66f89c59c979" alt="Manipulator and probe in pinpoint moving in sync">
9
10
 
@@ -13,7 +14,7 @@ Socket.IO-compliant application (such
13
14
  as [Pinpoint](https://github.com/VirtualBrainLab/Pinpoint))
14
15
  to communicate with manipulators used in electrophysiology experiments.
15
16
 
16
- Currently, Ephys Link only supports Sensapex uMp-4 Micromanipulators and New Scale 3-axis
17
+ Currently, Ephys Link only supports Sensapex uMp-4 and uMp-3 Micromanipulators and New Scale 3-axis
17
18
  manipulators. However, this platform is designed to be extensible to other
18
19
  manipulators and more may be added in the future.
19
20
 
@@ -84,8 +85,8 @@ Run the following commands in a terminal to start the server for the desired man
84
85
 
85
86
  | Manipulator Platform | Command |
86
87
  |--------------------------------------|--------------------------------------|
87
- | Sensapex UMP-4 | `ephys-link` |
88
- | Sensapex UMP-3 | `ephys-link -t ump3` |
88
+ | Sensapex uMp-4 | `ephys-link` |
89
+ | Sensapex uMp-3 | `ephys-link -t ump3` |
89
90
  | New Scale | `ephys-link -t new_scale` |
90
91
  | New Scale via Pathfinder HTTP server | `ephys-link -t new_scale_pathfinder` |
91
92
 
@@ -0,0 +1,104 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "ephys-link"
7
+ dynamic = ["version"]
8
+ description = "A Python Socket.IO server that allows any Socket.IO-compliant application to communicate with manipulators used in electrophysiology experiments."
9
+ readme = "README.md"
10
+ requires-python = ">=3.8, <3.13"
11
+ license = "GPL-3.0-only"
12
+ keywords = ["socket-io", "manipulator", "electrophysiology", "ephys", "sensapex", "neuroscience", "neurotech", "virtualbrainlab", "new-scale"]
13
+ authors = [{ name = "Kenneth Yang", email = "kjy5@uw.edu" }]
14
+ maintainers = [{ name = "Kenneth Yang", email = "kjy5@uw.edu" }]
15
+ classifiers = [
16
+ "Programming Language :: Python",
17
+ "Programming Language :: Python :: 3.8",
18
+ "Programming Language :: Python :: 3.9",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: Implementation :: CPython",
23
+ "Programming Language :: Python :: Implementation :: PyPy",
24
+ "Programming Language :: Python :: 3",
25
+ "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
26
+ "Operating System :: OS Independent",
27
+ "Intended Audience :: End Users/Desktop",
28
+ "Intended Audience :: Healthcare Industry",
29
+ "Intended Audience :: Science/Research",
30
+ "Topic :: Scientific/Engineering :: Medical Science Apps.",
31
+ ]
32
+ dependencies = [
33
+ "aiohttp==3.9.1",
34
+ "pyserial==3.5",
35
+ "python-socketio==5.10.0",
36
+ "pythonnet==3.0.3",
37
+ "wheel==0.42.0",
38
+ "sensapex==1.400.0",
39
+ ]
40
+
41
+ [project.urls]
42
+ Documentation = "https://virtualbrainlab.org/ephys_link/installation_and_use.html"
43
+ Issues = "https://github.com/VirtualBrainLab/ephys-link/issues"
44
+ Source = "https://github.com/VirtualBrainLab/ephys-link"
45
+
46
+ [project.scripts]
47
+ ephys-link = "ephys_link.__main__:main"
48
+ ephys_link = "ephys_link.__main__:main"
49
+ el = "ephys_link.__main__:main"
50
+
51
+ [tool.hatch.version]
52
+ path = "src/ephys_link/__about__.py"
53
+
54
+ [tool.hatch.build.targets.sdist]
55
+ exclude = ["/.github", "/.idea"]
56
+
57
+ [tool.hatch.envs.default]
58
+ dependencies = [
59
+ "coverage[toml]>=6.5",
60
+ "pytest",
61
+ ]
62
+ [tool.hatch.envs.default.scripts]
63
+ test = "pytest {args:tests}"
64
+ test-cov = "coverage run -m pytest {args:tests}"
65
+ cov-report = [
66
+ "- coverage combine",
67
+ "coverage report",
68
+ ]
69
+ cov = [
70
+ "test-cov",
71
+ "cov-report",
72
+ ]
73
+
74
+ [[tool.hatch.envs.all.matrix]]
75
+ python = ["3.8", "3.9", "3.10", "3.11", "3.12"]
76
+
77
+ [tool.hatch.envs.types]
78
+ dependencies = [
79
+ "mypy>=1.0.0",
80
+ ]
81
+ [tool.hatch.envs.types.scripts]
82
+ check = "mypy --install-types --non-interactive {args:src/ephys_link tests}"
83
+
84
+ [tool.coverage.run]
85
+ source_pkgs = ["ephys_link", "tests"]
86
+ branch = true
87
+ parallel = true
88
+ omit = [
89
+ "src/ephys_link/__about__.py",
90
+ ]
91
+
92
+ [tool.coverage.paths]
93
+ ephys_link = ["src/ephys_link", "*/ephys-link/src/ephys_link"]
94
+ tests = ["tests", "*/ephys-link/tests"]
95
+
96
+ [tool.coverage.report]
97
+ exclude_lines = [
98
+ "no cov",
99
+ "if __name__ == .__main__.:",
100
+ "if TYPE_CHECKING:",
101
+ ]
102
+
103
+ [tool.ruff.lint]
104
+ extend-ignore = ["T201", "PLW0603", "BLE001", "FBT001", "ARG002", "S310"]
@@ -0,0 +1 @@
1
+ __version__ = "1.0.6a0"
@@ -69,12 +69,9 @@ parser.add_argument(
69
69
  type=str,
70
70
  dest="type",
71
71
  default="sensapex",
72
- help='Manipulator type (i.e. "sensapex", "new_scale", or "new_scale_pathfinder").'
73
- ' Default: "sensapex"',
74
- )
75
- parser.add_argument(
76
- "-d", "--debug", dest="debug", action="store_true", help="Enable debug mode"
72
+ help='Manipulator type (i.e. "sensapex", "new_scale", or "new_scale_pathfinder").' ' Default: "sensapex"',
77
73
  )
74
+ parser.add_argument("-d", "--debug", dest="debug", action="store_true", help="Enable debug mode")
78
75
  parser.add_argument(
79
76
  "-p",
80
77
  "--port",
@@ -113,7 +110,7 @@ def main() -> None:
113
110
 
114
111
  # Parse arguments
115
112
  args = parser.parse_args()
116
- com.set_debug(args.debug)
113
+ com.DEBUG = args.debug
117
114
 
118
115
  # Setup serial port
119
116
  if args.serial != "no-e-stop":
@@ -4,23 +4,14 @@ Contains globally used helper functions and typed dictionaries (to be used as
4
4
  callback parameters)
5
5
  """
6
6
 
7
+ from __future__ import annotations
8
+
7
9
  from typing import TypedDict
8
10
 
9
11
  # Debugging flag
10
12
  DEBUG = False
11
13
 
12
14
 
13
- def set_debug(debug: bool) -> None:
14
- """Set debug flag
15
-
16
- :param debug: True to enable debug mode, False to disable
17
- :type debug: bool
18
- :return: None
19
- """
20
- global DEBUG
21
- DEBUG = debug
22
-
23
-
24
15
  def dprint(message: str) -> None:
25
16
  """Print message if debug is enabled
26
17
 
@@ -81,11 +72,9 @@ class GetManipulatorsOutputData(dict):
81
72
  :code:`{"manipulators": ["1", "2"], "error": ""}`
82
73
  """
83
74
 
84
- def __init__(
85
- self, manipulators: list, num_axes: int, dimensions: list, error: str
86
- ) -> None:
75
+ def __init__(self, manipulators: list, num_axes: int, dimensions: list, error: str) -> None:
87
76
  """Constructor"""
88
- super(GetManipulatorsOutputData, self).__init__(
77
+ super().__init__(
89
78
  manipulators=manipulators,
90
79
  num_axes=num_axes,
91
80
  dimensions=dimensions,
@@ -107,7 +96,7 @@ class PositionalOutputData(dict):
107
96
 
108
97
  def __init__(self, position: list, error: str) -> None:
109
98
  """Constructor"""
110
- super(PositionalOutputData, self).__init__(position=position, error=error)
99
+ super().__init__(position=position, error=error)
111
100
 
112
101
 
113
102
  class AngularOutputData(dict):
@@ -121,7 +110,21 @@ class AngularOutputData(dict):
121
110
 
122
111
  def __init__(self, angles: list, error: str) -> None:
123
112
  """Constructor"""
124
- super(AngularOutputData, self).__init__(angles=angles, error=error)
113
+ super().__init__(angles=angles, error=error)
114
+
115
+
116
+ class ShankCountOutputData(dict):
117
+ """Output format for (num_shanks, error)
118
+
119
+ :param shank_count: Number of shanks on the probe
120
+ :type shank_count: int
121
+ :param error: Error message
122
+ :type error: str
123
+ """
124
+
125
+ def __init__(self, shank_count: int, error: str) -> None:
126
+ """Constructor"""
127
+ super().__init__(shank_count=shank_count, error=error)
125
128
 
126
129
 
127
130
  class DriveToDepthOutputData(dict):
@@ -137,7 +140,7 @@ class DriveToDepthOutputData(dict):
137
140
 
138
141
  def __init__(self, depth: float, error: str) -> None:
139
142
  """Create drive to depth output data dictionary"""
140
- super(DriveToDepthOutputData, self).__init__(depth=depth, error=error)
143
+ super().__init__(depth=depth, error=error)
141
144
 
142
145
 
143
146
  class StateOutputData(dict):
@@ -153,4 +156,4 @@ class StateOutputData(dict):
153
156
 
154
157
  def __init__(self, state: bool, error: str) -> None:
155
158
  """Create state output data dictionary"""
156
- super(StateOutputData, self).__init__(state=state, error=error)
159
+ super().__init__(state=state, error=error)