88"""
99
1010from typing import final
11- from uuid import uuid4
1211
1312from vbl_aquarium .models .ephys_link import (
1413 AngularResponse ,
1514 BooleanStateResponse ,
16- EphysLinkOptions ,
1715 GetManipulatorsResponse ,
1816 PlatformInfo ,
1917 PositionalResponse ,
2321 SetPositionRequest ,
2422 ShankCountResponse ,
2523)
26- from vbl_aquarium .models .unity import Vector4
2724
28- from ephys_link .bindings . mpm_binding import MPMBinding
25+ from ephys_link .front_end . console import Console
2926from ephys_link .utils .base_binding import BaseBinding
30- from ephys_link .utils .console import Console
27+ from ephys_link .utils .constants import (
28+ EMERGENCY_STOP_MESSAGE ,
29+ NO_SET_POSITION_WHILE_INSIDE_BRAIN_ERROR ,
30+ did_not_reach_target_depth_error ,
31+ did_not_reach_target_position_error ,
32+ )
3133from ephys_link .utils .converters import vector4_to_array
32- from ephys_link .utils .startup import get_bindings
3334
3435
3536@final
3637class PlatformHandler :
3738 """Handler for platform commands."""
3839
39- def __init__ (self , options : EphysLinkOptions , console : Console ) -> None :
40+ def __init__ (self , binding : BaseBinding , console : Console ) -> None :
4041 """Initialize platform handler.
4142
4243 Args:
43- options: CLI options .
44+ binding: Binding instance for the platform .
4445 console: Console instance.
4546 """
46- # Store the CLI options.
47- self ._options = options
48-
4947 # Store the console.
5048 self ._console = console
5149
5250 # Define bindings based on platform type.
53- self ._bindings = self . _get_binding_instance ( options )
51+ self ._bindings = binding
5452
5553 # Record which IDs are inside the brain.
5654 self ._inside_brain : set [str ] = set ()
5755
58- # Generate a Pinpoint ID for proxy usage.
59- self ._pinpoint_id = str (uuid4 ())[:8 ]
60-
61- def _get_binding_instance (self , options : EphysLinkOptions ) -> BaseBinding :
62- """Match the platform type to the appropriate bindings.
63-
64- Args:
65- options: CLI options.
66-
67- Raises:
68- ValueError: If the platform type is not recognized.
69-
70- Returns:
71- Bindings for the specified platform type.
72- """
73-
74- # What the user supplied.
75- selected_type = options .type
76-
77- for binding_type in get_bindings ():
78- binding_cli_name = binding_type .get_cli_name ()
79-
80- # Notify deprecation of "ump-4" and "ump-3" CLI options and fix.
81- if selected_type in ("ump-4" , "ump-3" ):
82- self ._console .error_print (
83- "DEPRECATION" ,
84- f"CLI option '{ selected_type } ' is deprecated and will be removed in v3.0.0. Use 'ump' instead." ,
85- )
86- selected_type = "ump"
87-
88- if binding_cli_name == selected_type :
89- # Pass in HTTP port for Pathfinder MPM.
90- if binding_cli_name == "pathfinder-mpm" :
91- return MPMBinding (options .mpm_port )
92-
93- # Otherwise just return the binding.
94- return binding_type ()
95-
96- # Raise an error if the platform type is not recognized.
97- error_message = f'Platform type "{ options .type } " not recognized.'
98- self ._console .critical_print (error_message )
99- raise ValueError (error_message )
100-
10156 # Platform metadata.
10257
10358 def get_display_name (self ) -> str :
@@ -152,7 +107,7 @@ async def get_position(self, manipulator_id: str) -> PositionalResponse:
152107 )
153108 except Exception as e : # noqa: BLE001
154109 self ._console .exception_error_print ("Get Position" , e )
155- return PositionalResponse (error = str (e ))
110+ return PositionalResponse (error = self . _console . pretty_exception (e ))
156111 else :
157112 return PositionalResponse (position = unified_position )
158113
@@ -202,9 +157,8 @@ async def set_position(self, request: SetPositionRequest) -> PositionalResponse:
202157 try :
203158 # Disallow setting manipulator position while inside the brain.
204159 if request .manipulator_id in self ._inside_brain :
205- error_message = 'Can not move manipulator while inside the brain. Set the depth ("set_depth") instead.'
206- self ._console .error_print ("Set Position" , error_message )
207- return PositionalResponse (error = error_message )
160+ self ._console .error_print ("Set Position" , NO_SET_POSITION_WHILE_INSIDE_BRAIN_ERROR )
161+ return PositionalResponse (error = NO_SET_POSITION_WHILE_INSIDE_BRAIN_ERROR )
208162
209163 # Move to the new position.
210164 final_platform_position = await self ._bindings .set_position (
@@ -222,11 +176,7 @@ async def set_position(self, request: SetPositionRequest) -> PositionalResponse:
222176
223177 # Check if the axis is within the movement tolerance.
224178 if abs (axis ) > self ._bindings .get_movement_tolerance ():
225- error_message = (
226- f"Manipulator { request .manipulator_id } did not reach target"
227- f" position on axis { list (Vector4 .model_fields .keys ())[index ]} ."
228- f" Requested: { request .position } , got: { final_unified_position } ."
229- )
179+ error_message = did_not_reach_target_position_error (request , index , final_unified_position )
230180 self ._console .error_print ("Set Position" , error_message )
231181 return PositionalResponse (error = error_message )
232182 except Exception as e : # noqa: BLE001
@@ -246,26 +196,22 @@ async def set_depth(self, request: SetDepthRequest) -> SetDepthResponse:
246196 """
247197 try :
248198 # Move to the new depth.
249- final_platform_depth = await self ._bindings .set_depth (
199+ final_depth = await self ._bindings .set_depth (
250200 manipulator_id = request .manipulator_id ,
251- depth = self . _bindings . unified_space_to_platform_space ( Vector4 ( w = request .depth )). w ,
201+ depth = request .depth ,
252202 speed = request .speed ,
253203 )
254- final_unified_depth = self ._bindings .platform_space_to_unified_space (Vector4 (w = final_platform_depth )).w
255204
256205 # Return error if movement did not reach target within tolerance.
257- if abs (final_unified_depth - request .depth ) > self ._bindings .get_movement_tolerance ():
258- error_message = (
259- f"Manipulator { request .manipulator_id } did not reach target depth."
260- f" Requested: { request .depth } , got: { final_unified_depth } ."
261- )
206+ if abs (final_depth - request .depth ) > self ._bindings .get_movement_tolerance ():
207+ error_message = did_not_reach_target_depth_error (request , final_depth )
262208 self ._console .error_print ("Set Depth" , error_message )
263209 return SetDepthResponse (error = error_message )
264210 except Exception as e : # noqa: BLE001
265211 self ._console .exception_error_print ("Set Depth" , e )
266212 return SetDepthResponse (error = self ._console .pretty_exception (e ))
267213 else :
268- return SetDepthResponse (depth = final_unified_depth )
214+ return SetDepthResponse (depth = final_depth )
269215
270216 async def set_inside_brain (self , request : SetInsideBrainRequest ) -> BooleanStateResponse :
271217 """Mark a manipulator as inside the brain or not.
@@ -278,16 +224,11 @@ async def set_inside_brain(self, request: SetInsideBrainRequest) -> BooleanState
278224 Returns:
279225 Inside brain state of the manipulator and an error message if any.
280226 """
281- try :
282- if request .inside :
283- self ._inside_brain .add (request .manipulator_id )
284- else :
285- self ._inside_brain .discard (request .manipulator_id )
286- except Exception as e : # noqa: BLE001
287- self ._console .exception_error_print ("Set Inside Brain" , e )
288- return BooleanStateResponse (error = self ._console .pretty_exception (e ))
227+ if request .inside :
228+ self ._inside_brain .add (request .manipulator_id )
289229 else :
290- return BooleanStateResponse (state = request .inside )
230+ self ._inside_brain .discard (request .manipulator_id )
231+ return BooleanStateResponse (state = request .inside )
291232
292233 async def stop (self , manipulator_id : str ) -> str :
293234 """Stop a manipulator.
@@ -316,12 +257,12 @@ async def stop_all(self) -> str:
316257 for manipulator_id in await self ._bindings .get_manipulators ():
317258 await self ._bindings .stop (manipulator_id )
318259 except Exception as e : # noqa: BLE001
319- self ._console .exception_error_print ("Stop" , e )
260+ self ._console .exception_error_print ("Stop All " , e )
320261 return self ._console .pretty_exception (e )
321262 else :
322263 return ""
323264
324265 async def emergency_stop (self ) -> None :
325266 """Stops all manipulators with a message."""
326- self ._console .critical_print ("Emergency Stopping All Manipulators..." )
267+ self ._console .critical_print (EMERGENCY_STOP_MESSAGE )
327268 _ = await self .stop_all ()
0 commit comments