Closed canismarko closed 5 months ago
Here's the stack trace from 25-ID-C if I comment out the robot section of the TOML configuration file.
In [1]: import haven
In [2]: haven.load_instrument()
/home/beams0/S25IDCUSER/src/haven-dev/src/haven/instrument/load_instrument.py:54: RuntimeWarning: coroutine 'make_device' was never awaited
coros = (
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
/home/beams0/S25IDCUSER/src/haven-dev/src/haven/instrument/load_instrument.py:54: RuntimeWarning: coroutine 'load_ion_chamber' was never awaited
coros = (
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
/home/beams0/S25IDCUSER/src/haven-dev/src/haven/instrument/load_instrument.py:54: RuntimeWarning: coroutine 'make_xspress_device' was never awaited
coros = (
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
/home/beams0/S25IDCUSER/src/haven-dev/src/haven/instrument/load_instrument.py:54: RuntimeWarning: coroutine 'make_dxp_device' was never awaited
coros = (
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
/home/beams0/S25IDCUSER/src/haven-dev/src/haven/instrument/load_instrument.py:54: RuntimeWarning: coroutine 'make_energy_device' was never awaited
coros = (
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
Cell In[2], line 1
----> 1 haven.load_instrument()
File /home/beams0/S25IDCUSER/src/haven-dev/src/haven/instrument/load_instrument.py:116, in load_instrument(registry, config, return_devices)
114 # Import devices concurrently
115 loop = asyncio.get_event_loop()
--> 116 devices = loop.run_until_complete(
117 aload_instrument(registry=registry, config=config)
118 )
119 # Also import some simulated devices for testing
120 devices += load_simulated_devices(config=config)
File /home/beams0/S25IDCUSER/micromamba/envs/haven-dev/lib/python3.9/asyncio/base_events.py:647, in BaseEventLoop.run_until_complete(self, future)
644 if not future.done():
645 raise RuntimeError('Event loop stopped before Future completed.')
--> 647 return future.result()
File /home/beams0/S25IDCUSER/src/haven-dev/src/haven/instrument/load_instrument.py:54, in aload_instrument(registry, config)
33 async def aload_instrument(
34 registry: InstrumentRegistry = default_registry, config: Mapping = None
35 ):
36 """Asynchronously load the beamline instrumentation into an instrument
37 registry.
38
(...)
52
53 """
---> 54 coros = (
55 *load_camera_coros(config=config),
56 *load_shutter_coros(config=config),
57 *load_aerotech_stage_coros(config=config),
58 *load_aps_coros(config=config),
59 *load_monochromator_coros(config=config),
60 *load_xray_source_coros(config=config),
61 *load_energy_positioner_coros(config=config),
62 *load_dxp_coros(config=config),
63 *load_xspress_coros(config=config),
64 *load_stage_coros(config=config),
65 *load_heater_coros(config=config),
66 *load_power_supply_coros(config=config),
67 *load_slit_coros(config=config),
68 *load_mirror_coros(config=config),
69 *load_table_coros(config=config),
70 *load_ion_chamber_coros(config=config),
71 *load_area_detector_coros(config=config),
72 *load_lerix_spectrometer_coros(config=config),
73 *load_robot_coros(config=config)
74 )
75 devices = await asyncio.gather(*coros)
76 # Load the motor devices last so that we can check for existing
77 # motors in the registry
File /home/beams0/S25IDCUSER/src/haven-dev/src/haven/instrument/robot.py:108, in load_robot_coros(config)
106 if config is None:
107 config = load_config()
--> 108 robots = config["robot"]
109 for name, cfg in robots.items():
110 yield make_device(Robot, name=name, labels={"robots"}, prefix=cfg["prefix"])
KeyError: 'robot'
@yannachen I think this is done now, right? Can we close this issue?
Yes, it is done. I am working on the plan and its test.
When creating the Robot() device objects, we look for a configuration entry "robot". If there isn't an entry like that, then there's a KeyError when doing
config['robot']
.I'm thinking we need to use the dictionaries get() method and give it a sensible default value.