ephys-link 2.0.0b6__py3-none-any.whl → 2.0.0b10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,138 +0,0 @@
1
- """Bindings for Sensapex uMp-3 platform.
2
-
3
- Usage: Instantiate Ump4Bindings to interact with the Sensapex uMp-4 platform.
4
- """
5
-
6
- from asyncio import get_running_loop
7
-
8
- from sensapex import UMP, SensapexDevice
9
- from vbl_aquarium.models.unity import Vector3, Vector4
10
-
11
- from ephys_link.util.base_bindings import BaseBindings
12
- from ephys_link.util.common import (
13
- RESOURCES_PATH,
14
- array_to_vector4,
15
- scalar_mm_to_um,
16
- um_to_mm,
17
- vector4_to_array,
18
- vector_mm_to_um,
19
- )
20
-
21
-
22
- class Ump3Bindings(BaseBindings):
23
- """Bindings for UMP-3 platform"""
24
-
25
- def __init__(self) -> None:
26
- """Initialize UMP-3 bindings."""
27
-
28
- # Establish connection to Sensapex API (exit if connection fails).
29
- UMP.set_library_path(RESOURCES_PATH)
30
- self._ump = UMP.get_ump()
31
- if self._ump is None:
32
- error_message = "Unable to connect to uMp"
33
- raise ValueError(error_message)
34
-
35
- async def get_manipulators(self) -> list[str]:
36
- return list(map(str, self._ump.list_devices()))
37
-
38
- async def get_axes_count(self) -> int:
39
- return 3
40
-
41
- def get_dimensions(self) -> Vector4:
42
- return Vector4(x=20, y=20, z=20, w=20)
43
-
44
- async def get_position(self, manipulator_id: str) -> Vector4:
45
- manipulator_position = self._get_device(manipulator_id).get_pos(1)
46
-
47
- # Add the depth axis to the end of the position.
48
- manipulator_position.append(manipulator_position[0])
49
-
50
- # Convert and return.
51
- return um_to_mm(array_to_vector4(manipulator_position))
52
-
53
- # noinspection PyTypeChecker
54
- async def get_angles(self, _: str) -> Vector3:
55
- """uMp-3 does not support getting angles so raise an error.
56
-
57
- :raises: AttributeError
58
- """
59
- error_message = "UMP-3 does not support getting angles"
60
- raise AttributeError(error_message)
61
-
62
- # noinspection PyTypeChecker
63
- async def get_shank_count(self, _: str) -> int:
64
- """uMp-3 does not support getting shank count so raise an error.
65
-
66
- :raises: AttributeError
67
- """
68
- error_message = "UMP-3 does not support getting shank count"
69
- raise AttributeError(error_message)
70
-
71
- def get_movement_tolerance(self) -> float:
72
- return 0.001
73
-
74
- # noinspection DuplicatedCode
75
- async def set_position(self, manipulator_id: str, position: Vector4, speed: float) -> Vector4:
76
- # Convert position to micrometers.
77
- target_position_um = vector_mm_to_um(position)
78
-
79
- # Request movement.
80
- movement = self._get_device(manipulator_id).goto_pos(
81
- vector4_to_array(target_position_um), scalar_mm_to_um(speed)
82
- )
83
-
84
- # Wait for movement to complete.
85
- await get_running_loop().run_in_executor(None, movement.finished_event.wait, None)
86
-
87
- # Handle interrupted movement.
88
- if movement.interrupted:
89
- error_message = f"Manipulator {manipulator_id} interrupted: {movement.interrupt_reason}"
90
- raise RuntimeError(error_message)
91
-
92
- return um_to_mm(array_to_vector4(movement.last_pos))
93
-
94
- async def set_depth(self, manipulator_id: str, depth: float, speed: float) -> float:
95
- # Augment current position with depth.
96
- current_position = await self.get_position(manipulator_id)
97
- new_platform_position = current_position.model_copy(update={"x": depth})
98
-
99
- # Make the movement.
100
- final_platform_position = await self.set_position(manipulator_id, new_platform_position, speed)
101
-
102
- # Return the final depth.
103
- return float(final_platform_position.w)
104
-
105
- async def stop(self, manipulator_id: str) -> None:
106
- self._get_device(manipulator_id).stop()
107
-
108
- def platform_space_to_unified_space(self, platform_space: Vector4) -> Vector4:
109
- # unified <- platform
110
- # +x <- +y
111
- # +y <- -x
112
- # +z <- -z
113
- # +d <- +d/x
114
-
115
- return Vector4(
116
- x=platform_space.y,
117
- y=self.get_dimensions().x - platform_space.x,
118
- z=self.get_dimensions().z - platform_space.z,
119
- w=platform_space.w,
120
- )
121
-
122
- def unified_space_to_platform_space(self, unified_space: Vector4) -> Vector4:
123
- # platform <- unified
124
- # +x <- -y
125
- # +y <- +x
126
- # +z <- -z
127
- # +d/x <- +d
128
-
129
- return Vector4(
130
- x=self.get_dimensions().y - unified_space.y,
131
- y=unified_space.x,
132
- z=self.get_dimensions().z - unified_space.z,
133
- w=unified_space.w,
134
- )
135
-
136
- # Helper methods.
137
- def _get_device(self, manipulator_id: str) -> SensapexDevice:
138
- return self._ump.get_device(int(manipulator_id))
Binary file
Binary file
ephys_link/util/common.py DELETED
@@ -1,120 +0,0 @@
1
- # ruff: noqa: T201
2
- """Commonly used utility functions and constants."""
3
-
4
- from os.path import join
5
- from pathlib import Path
6
-
7
- from packaging.version import parse
8
- from requests import get
9
- from vbl_aquarium.models.unity import Vector4
10
-
11
- from ephys_link.__about__ import __version__
12
-
13
- # Ephys Link ASCII.
14
- ASCII = r"""
15
- ______ _ _ _ _
16
- | ____| | | | | (_) | |
17
- | |__ _ __ | |__ _ _ ___ | | _ _ __ | | __
18
- | __| | '_ \| '_ \| | | / __| | | | | '_ \| |/ /
19
- | |____| |_) | | | | |_| \__ \ | |____| | | | | <
20
- |______| .__/|_| |_|\__, |___/ |______|_|_| |_|_|\_\
21
- | | __/ |
22
- |_| |___/
23
- """
24
-
25
- # Absolute path to the resource folder.
26
- RESOURCES_PATH = join(str(Path(__file__).parent.parent.absolute()), "resources")
27
-
28
- # Ephys Link Port
29
- PORT = 3000
30
-
31
-
32
- # Server startup.
33
- def server_preamble() -> None:
34
- """Print the server startup preamble."""
35
- print(ASCII)
36
- print(__version__)
37
- print()
38
- print("This is the Ephys Link server window.")
39
- print("You may safely leave it running in the background.")
40
- print("To stop it, close this window or press CTRL + Pause/Break.")
41
- print()
42
-
43
-
44
- def check_for_updates() -> None:
45
- """Check for updates to the Ephys Link."""
46
- response = get("https://api.github.com/repos/VirtualBrainLab/ephys-link/tags", timeout=10)
47
- latest_version = response.json()[0]["name"]
48
- if parse(latest_version) > parse(__version__):
49
- print(f"Update available: {latest_version} !")
50
- print("Download at: https://github.com/VirtualBrainLab/ephys-link/releases/latest")
51
-
52
-
53
- # Unit conversions
54
-
55
-
56
- def scalar_mm_to_um(mm: float) -> float:
57
- """Convert scalar values of millimeters to micrometers.
58
-
59
- :param mm: Scalar value in millimeters.
60
- :type mm: float
61
- :returns: Scalar value in micrometers.
62
- :rtype: float
63
- """
64
- return mm * 1_000
65
-
66
-
67
- def vector_mm_to_um(mm: Vector4) -> Vector4:
68
- """Convert vector values of millimeters to micrometers.
69
-
70
- :param mm: Vector in millimeters.
71
- :type mm: Vector4
72
- :returns: Vector in micrometers.
73
- :rtype: Vector4
74
- """
75
- return mm * 1_000
76
-
77
-
78
- def um_to_mm(um: Vector4) -> Vector4:
79
- """Convert micrometers to millimeters.
80
-
81
- :param um: Length in micrometers.
82
- :type um: Vector4
83
- :returns: Length in millimeters.
84
- :rtype: Vector4
85
- """
86
- return um / 1_000
87
-
88
-
89
- def vector4_to_array(vector4: Vector4) -> list[float]:
90
- """Convert a Vector4 to a list of floats.
91
-
92
- :param vector4: Vector4 to convert.
93
- :type vector4: :class:`vbl_aquarium.models.unity.Vector4`
94
- :return: List of floats.
95
- :rtype: list[float]
96
- """
97
- return [vector4.x, vector4.y, vector4.z, vector4.w]
98
-
99
-
100
- def array_to_vector4(array: list[float]) -> Vector4:
101
- """Convert a list of floats to a Vector4.
102
-
103
- :param array: List of floats.
104
- :type array: list[float]
105
- :return: First four elements of the list as a Vector4 padded with zeros if necessary.
106
- :rtype: :class:`vbl_aquarium.models.unity.Vector4`
107
- """
108
-
109
- def get_element(this_array: list[float], index: int) -> float:
110
- try:
111
- return this_array[index]
112
- except IndexError:
113
- return 0.0
114
-
115
- return Vector4(
116
- x=get_element(array, 0),
117
- y=get_element(array, 1),
118
- z=get_element(array, 2),
119
- w=get_element(array, 3),
120
- )
@@ -1,166 +0,0 @@
1
- Metadata-Version: 2.3
2
- Name: ephys-link
3
- Version: 2.0.0b6
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 :: Microsoft :: Windows
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.10
29
- Requires-Dist: aiohttp==3.10.8
30
- Requires-Dist: colorama==0.4.6
31
- Requires-Dist: platformdirs==4.3.6
32
- Requires-Dist: pyserial==3.5
33
- Requires-Dist: python-socketio[asyncio-client]==5.11.4
34
- Requires-Dist: pythonnet==3.0.4
35
- Requires-Dist: requests==2.32.3
36
- Requires-Dist: rich==13.8.1
37
- Requires-Dist: sensapex==1.400.1
38
- Requires-Dist: vbl-aquarium==0.0.22
39
- Description-Content-Type: text/markdown
40
-
41
- # Electrophysiology Manipulator Link
42
-
43
- [![PyPI version](https://badge.fury.io/py/ephys-link.svg)](https://badge.fury.io/py/ephys-link)
44
- [![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)
45
- [![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)
46
- [![Hatch project](https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg)](https://github.com/pypa/hatch)
47
- [![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)
48
-
49
- <!-- [![Build](https://github.com/VirtualBrainLab/ephys-link/actions/workflows/build.yml/badge.svg)](https://github.com/VirtualBrainLab/ephys-link/actions/workflows/build.yml) -->
50
-
51
- <img width="100%" src="https://github.com/VirtualBrainLab/ephys-link/assets/82800265/0c7c60b1-0926-4697-a461-221554f82de1" alt="Manipulator and probe in pinpoint moving in sync">
52
-
53
- The [Electrophysiology Manipulator Link](https://github.com/VirtualBrainLab/ephys-link)
54
- (or Ephys Link for short) is a Python [Socket.IO](https://socket.io/docs/v4/#what-socketio-is) server that allows any
55
- Socket.IO-compliant application (such
56
- as [Pinpoint](https://github.com/VirtualBrainLab/Pinpoint))
57
- to communicate with manipulators used in electrophysiology experiments.
58
-
59
- **Supported Manipulators:**
60
-
61
- | Manufacturer | Model |
62
- |--------------|-------------------------------------------------------------------------|
63
- | Sensapex | <ul> <li>uMp-4</li> <li>uMp-3</li> </ul> |
64
- | New Scale | <ul> <li>Pathfinder MPM Control v2.8+</li> <li>M3-USB-3:1-EP</li> </ul> |
65
-
66
- Ephys Link is an open and extensible platform. It is designed to easily support integration with other manipulators.
67
-
68
- For more information regarding the server's implementation and how the code is organized, see
69
- the [package's development documentation](https://virtualbrainlab.org/ephys_link/development.html).
70
-
71
- For detailed descriptions of the server's API, see
72
- the [API reference](https://virtualbrainlab.org/api_reference_ephys_link.html).
73
-
74
- # Installation
75
-
76
- ## Prerequisites
77
-
78
- 1. An **x86 Windows PC is required** to run the server.
79
- 2. For Sensapex devices, the controller unit must be connected via an ethernet
80
- cable and powered. A USB-to-ethernet adapter is acceptable. For New Scale manipulators,
81
- the controller unit must be connected via USB and be powered by a 6V power
82
- supply.
83
- 3. To use the emergency stop feature, ensure an Arduino with
84
- the [StopSignal](https://github.com/VirtualBrainLab/StopSignal) sketch is
85
- connected to the computer. Follow the instructions on that repo for how to
86
- set up the Arduino.
87
-
88
- **NOTE:** Ephys Link is an HTTP server without cross-origin support. The server
89
- is currently designed to interface with local/desktop instances of Pinpoint. It
90
- will not work with the web browser versions of Pinpoint at this time.
91
-
92
- ## Launch from Pinpoint (Recommended)
93
-
94
- Pinpoint comes bundled with the correct version of Ephys Link. If you are using Pinpoint on the same computer your
95
- manipulators are connected to, you can launch the server from within Pinpoint. Follow the instructions in
96
- the [Pinpoint documentation](https://virtualbrainlab.org/pinpoint/tutorials/tutorial_ephys_link.html#configure-and-launch-ephys-link).
97
-
98
- ## Install as Standalone Executable
99
-
100
- 1. Download the latest executable from
101
- the [releases page](https://github.com/VirtualBrainLab/ephys-link/releases/latest).
102
- 2. Double-click the executable file to launch the configuration window.
103
- 1. Take note of the IP address and port. **Copy this information into Pinpoint to connect**.
104
- 3. Select the desired configuration and click "Launch Server".
105
-
106
- The configuration window will close and the server will launch. Your configurations will be saved for future use.
107
-
108
- To connect to the server from Pinpoint, provide the IP address and port. For example, if the server is running on the
109
- same computer that Pinpoint is, use
110
-
111
- - Server: `localhost`
112
- - Port: `8081`
113
-
114
- If the server is running on a different (local) computer, use the IP address of that computer as shown in the startup
115
- window instead of `localhost`.
116
-
117
- ## Install as a Python package
118
-
119
- ```bash
120
- pip install ephys-link
121
- ```
122
-
123
- Import main and run (this will launch the setup GUI).
124
-
125
- ```python
126
- from ephys_link.__main__ import main
127
-
128
- main()
129
- ```
130
-
131
- ## Install for Development
132
-
133
- 1. Clone the repository.
134
- 2. Install [Hatch](https://hatch.pypa.io/latest/install/)
135
- 3. In a terminal, navigate to the repository's root directory and run
136
-
137
- ```bash
138
- hatch shell
139
- ```
140
-
141
- This will create a virtual environment, install Python 12 (if not found), and install the package in editable mode.
142
-
143
- If you encounter any dependency issues (particularly with `aiohttp`), try installing the latest Microsoft Visual C++
144
- (MSVC v143+ x86/64) and the Windows SDK (10/11)
145
- via [Visual Studio Build Tools Installer](https://visualstudio.microsoft.com/visual-cpp-build-tools/).
146
-
147
- # Documentation and More Information
148
-
149
- Complete documentation including API usage and development installation can be
150
- found on the [Virtual Brain Lab Documentation page][docs] for Ephys Link.
151
-
152
- # Citing
153
-
154
- If this project is used as part of a research project you should cite
155
- the [Pinpoint repository][Pinpoint]. Please email
156
- Dan ([dbirman@uw.edu](mailto:dbirman@uw.edu)) if you have questions.
157
-
158
- Please reach out to Kenneth ([kjy5@uw.edu](mailto:kjy5@uw.edu)) for questions
159
- about the Electrophysiology Manipulator Link server. Bugs may be reported
160
- through the issues tab.
161
-
162
- [Pinpoint]: https://github.com/VirtualBrainLab/Pinpoint
163
-
164
- [StopSignal]: https://github.com/VirtualBrainLab/StopSignal
165
-
166
- [docs]: https://virtualbrainlab.org/ephys_link/installation_and_use.html
@@ -1,27 +0,0 @@
1
- ephys_link/__about__.py,sha256=Fnner2tzgTA5rbbqCtZskrgDUNN_ccYtXn_spXP2SvY,25
2
- ephys_link/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- ephys_link/__main__.py,sha256=KSwJO4gPQAZitNSNChD1NjkO2j3pc8RA2dkRbiaq32w,1368
4
- ephys_link/back_end/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- ephys_link/back_end/platform_handler.py,sha256=zPcQux1yEaXEbwkWt2TcnrmpZ0NNXHWXwQhP0_wABwA,13295
6
- ephys_link/back_end/server.py,sha256=QZu8deE57BxULfUutPQ41q3HTmr94nPyzaIT-JoOK2I,8026
7
- ephys_link/bindings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- ephys_link/bindings/fake_bindings.py,sha256=Dk9Bpv4XTYa6ooh5Ge_5-o3IRzdazj5pYMcp3O41UJI,1936
9
- ephys_link/bindings/mpm_bindings.py,sha256=e4whLU7mJm-Mbw6O2ua6fPHBZNnCiyyGiePEVBr3zzY,9818
10
- ephys_link/bindings/ump_3_bindings.py,sha256=7u97x3yAYdX-1PgLlO-psJvsOfCxJMCLt9-Jpc1u1a8,4799
11
- ephys_link/bindings/ump_4_bindings.py,sha256=SaDToxDLKK3LBfufgukjl5WxV4JHhTF9oO4vg7l93To,4535
12
- ephys_link/front_end/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- ephys_link/front_end/cli.py,sha256=KJBSWqdz4T5z0Zor1tJSHTJKZeMcHAJf5gXXu38wQPU,3105
14
- ephys_link/front_end/gui.py,sha256=_gE6zFhFnzHPSyYd9MBvfK5xmDZHsUXcETDHzH66QzU,7518
15
- ephys_link/resources/CP210xManufacturing.dll,sha256=aM9k_XABjkq0TOMiIw8HeteB40zqEkUDNO8wo91EdYI,810232
16
- ephys_link/resources/NstMotorCtrl.dll,sha256=Xtpr3vBcxhcsOUGvgVEwYtGPvKEqDctIUGCK36GfU2Q,155136
17
- ephys_link/resources/SiUSBXp.dll,sha256=187zlclZNNezCkU1o1CbICRAmKWJxbh8ahP6L6wo-_Y,469752
18
- ephys_link/resources/libum.dll,sha256=YaD4dwiSNohx-XxHjx2eQWPOBEVvUIXARvx37e_yqNw,316316
19
- ephys_link/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- ephys_link/util/base_bindings.py,sha256=ukomZftpwa8s_SV-jcwPSXmox0neXf8-uyie_NmiRro,5349
21
- ephys_link/util/common.py,sha256=Pk7uVqEMFMPKNpeucWda_GfnHogRszej5G5qYkt43d8,3455
22
- ephys_link/util/console.py,sha256=NvUH-Fp4nzkgrqQOcylctf46x4AW-qAphrtisepk1xY,4325
23
- ephys_link-2.0.0b6.dist-info/METADATA,sha256=MFmvagTs4lKlDgJ3rveMkpQ4qQJsGr6ik-PJejh0Ay4,7944
24
- ephys_link-2.0.0b6.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
25
- ephys_link-2.0.0b6.dist-info/entry_points.txt,sha256=o8wV3AdnJ9o47vg9ymKxPNVq9pMdPq8UZHE_iyAJx-k,124
26
- ephys_link-2.0.0b6.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
27
- ephys_link-2.0.0b6.dist-info/RECORD,,
File without changes