SPMMicroscope class and SPM_Scan sub-device - #131
Conversation
update_from_main
branch's update
|
Hi Boris, Gerd |
| def _get_proxy(self, name: str) -> tango.DeviceProxy: | ||
| """Return the sub-device proxy or raise a clear DevFailed.""" | ||
| proxy = self._device_proxies.get(name) | ||
| if proxy is None: | ||
| tango.Except.throw_exception( | ||
| 'DeviceNotConfigured', | ||
| f"No '{name}' device is configured. " | ||
| f"Set {name}_device_address in the Tango DB / config yaml.", | ||
| f'{name}', | ||
| ) | ||
| try: | ||
| proxy.ping() # type: ignore | ||
| except tango.DevFailed: | ||
| tango.Except.throw_exception( | ||
| 'DeviceNotAccessible', | ||
| f"The '{name}' device at '{proxy.dev_name()}' is not responding. " # type: ignore | ||
| f"Check that its server is running.", | ||
| f'{name}', | ||
| ) | ||
| return proxy |
There was a problem hiding this comment.
Just trying to understand, why would you need _get_proxy if you already have get_device_proxies .
| @tango.server.command(dtype_out=str) | ||
| def acquire_spectrum(self) -> str: | ||
| """Acquire a spectrum using SPECTROSCOPY device settings; returns a DATA/Tiled uid.""" | ||
| return self._get_proxy('spectroscopy').acquire_spectrum() |
There was a problem hiding this comment.
I see, you call the _get_proxy here based on naming in _connect_device_proxies
There was a problem hiding this comment.
I guess Jupiter_api will inherit the class SPMMicroscope
| # ------------------------------------------------------------------ | ||
| # Abstract methods — vendor-specific | ||
| # ------------------------------------------------------------------ | ||
|
|
There was a problem hiding this comment.
I wonder if this vendor specific methods should live here? Can we architect in a way that it is vendor neutral?
There was a problem hiding this comment.
Or maybe there should be a spm_stage_jupiter_api which inherits from spm_stage and fills in the Vendor parts?
There was a problem hiding this comment.
Hi, Utkarsh! It is not vendor specific methods - they are abstract "placeholders" that should be realized in the jupyter_api or bruker_api
| # ------------------------------------------------------------------ | ||
| # Abstract methods — vendor-specific | ||
| # ------------------------------------------------------------------ |
There was a problem hiding this comment.
Similar comment as done on - https://github.com/pycroscopy/asyncroscopy/pull/131/changes#r3691417522
| # ------------------------------------------------------------------ | ||
| # Abstract methods — vendor-specific | ||
| # ------------------------------------------------------------------ |
There was a problem hiding this comment.
Similar comment as done on - https://github.com/pycroscopy/asyncroscopy/pull/131/changes#r3691417522
| # ------------------------------------------------------------------ | ||
| # Abstract methods — vendor-specific | ||
| # ------------------------------------------------------------------ |
There was a problem hiding this comment.
Similar comment as done on - https://github.com/pycroscopy/asyncroscopy/pull/131/changes#r3691417522
|
Overall great PR. Looking forward to see Extra suggestions:
|
| """Approach the tip to the surface; returns resulting approach state as JSON.""" | ||
| proxy = self._get_proxy('approach') | ||
| proxy.approach() | ||
| return json.dumps({'approached': bool(proxy.approached)}) |
There was a problem hiding this comment.
I would suggest to avoid json.dump where it can be avoided and directly use PyTango dtype. As PyTango commands internally handles serialization and desiralization.
This reference can be useful:
https://tango-controls.readthedocs.io/projects/pytango/en/latest/api/data_types.html
|
@utkarshp1161 thanks again for the review. Could you please take a look on the changes I made. Thank you very much! |
SPM: abstract microscope facade and scan device
scanning_probe_microscope.py— rewrittenSPMMicroscopeas a thinorchestrator. It connects to the sub-devices (scan, feedback, approach,
stage, spectroscopy) via DeviceProxy and delegates single-subsystem
commands to them.
Only instrument-global state stays abstract (
_get_spm_mode,_get_meter_values). All commands return JSON strings confirming the resulting state; missing or unreachable sub-devices raise a clearDevFailedvia the_get_proxyhelper.get_microscope_statereportsNOT_CONFIGURED/UNREACHABLEinstead offailing.
hardware/scan.py— new abstractSPM_SCANdevice. Unlike the EM SCAN(settings holder only), it owns both the scan frame parameters and scan
execution. Vendor-specific behaviour is isolated in four hooks:
_hw_read_scan_params,_hw_write_scan_param,_hw_acquire_scan,_hw_stop_scan.Attribute writes are pushed to hardware and all
parameters are read back, so clients always see hardware-accepted values.
acquire_scansaves via the existingsave_acquisition(scan parametersattached as dataset attributes) and returns the DATA/Tiled key;
stop_scanandrefresh_paramscomplete the command set.Not included yet
Concrete Jupiter classes, remaining sub-devices (feedback, approach,
stage, spectroscopy), tests, and the SPM config yaml — follow-up PRs.
Removes the old
spm_devices/spm_scan.pydraft.