by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Thomas A Caswell
    @tacaswell
    are there example config files someplace?
    Kyle Sunden
    @ksunden_gitlab

    A valid config file for that would be

    [example]
    port=39000

    (There is no real configuration just need to tell it which tcp port to serve on)

    Till Stensitzki
    @Tillsten
    I am not a huge fan of the the whole obj.set('that', 5) syntax, I always finding that a little unpythonic.
    Blaise Thompson
    @untzag
    @Tillsten I agree actually
    but what @ksunden_gitlab and I are trying to build is a JSON-RPC spec, not a python interface
    the idea is that you could write daemons and clients in any old language
    of course right now we only actually have python---anyway that's the idea :smile:
    Till Stensitzki
    @Tillsten
    I think you are reinventing epics/tango
    Blaise Thompson
    @untzag
    yeah I could believe you...
    Till Stensitzki
    @Tillsten
    But I really dig the traits idea.
    Kyle Sunden
    @ksunden_gitlab
    That is our real core, I think, though the strong interface is also key
    Blaise Thompson
    @untzag
    can you say more about why EPICS was too much for you Till?
    Till Stensitzki
    @Tillsten
    Before I came in the lab was running Visual Basic 6, hence windows computers
    I think epic is almost never used outside the bigger instituitions
    Because the hurdle to install it is really highm, if you don't have decidated stuff for that, which many people dont.
    The alternative is "just" writing an dll wrapper or use some serial commands via visa/pyserial.
    Thomas A Caswell
    @tacaswell
    @untzag @ksunden_gitlab do you have a way to get push notifications from the daemons?
    Blaise Thompson
    @untzag
    nope
    strictly client intiated
    idea is that clients would have poll loops, if needed
    Kyle Sunden
    @ksunden_gitlab
    We do not, we designed with the idea that all requests would be initiated by the client, and return quickly
    Thomas A Caswell
    @tacaswell
    poll loops don't scale up well
    how does a motor tell you it got where it was going?
    Blaise Thompson
    @untzag
    so you call set_position
    and then you sit in a loop calling busy until it returns false
    and then (most of the time) you don't communicate with the motor at all until you need to move it again
    if you have a graphical interface you can call get_position while it's moving
    and have that streaming feedback experience
    Kyle Sunden
    @ksunden_gitlab
    Part of this is from the fact that JSON-RPC is an inheriently mono-directional protocol
    Blaise Thompson
    @untzag
    it's not optimized for tight timing---I guess that's just not something I've found necessary in my work
    Thomas A Caswell
    @tacaswell
    can I make the test motor have an appreciable move time?
    Blaise Thompson
    @untzag
    um...
    edit source? that's all I got. @ksunden_gitlab ?
    Kyle Sunden
    @ksunden_gitlab
    I can make one pretty quick (and just put the python in here)
    Thomas A Caswell
    @tacaswell
    if you don't have one handy don't worry about it
    Kyle Sunden
    @ksunden_gitlab
    
    import asyncio
    from yaqd_core import Hardware
    
    class SlowHardware(Hardware):
        _kind = "slow-hardware"
    
        def _set_position(self, position):
            self._loop.create_task(self.wait_and_set(position))
    
        async def wait_and_set(self, position):
            self._busy = True
            await asyncio.sleep(2)
            self._position = position
            self._busy = False
    
    if __name__ == "__main__":
        SlowHardware.main()
    Then just python slow_motor_test.py --config config.toml
    Or whatever you call the python file, rather
    (I will note that I did not put any protections in there for calling set_position multiple times while it is 'moving', more properly I would. Most real hardware you set the busy state via other means, so it can handle it fine, some you do have to prempt motion as its occurring.)
    Till Stensitzki
    @Tillsten
    isn't json rpc little bit slow for sensor readout?
    Thomas A Caswell
    @tacaswell
    from ophyd import Device, Component as Cpt, Signal, DeviceStatus
    
    
    class YaqMotor(Device):
        setpoint = Cpt(Signal, kind="hinted")
        readback = Cpt(Signal)
        busy = Cpt(Signal, kind="omitted")
    
        def __init__(self, port, *, name):
            self._client = yaqc.Client(port)
            super().__init__(name=name)
            # force initial reading
            self.read()
    
        def set(self, value):
            self._client.send("set_position", value)
            st = DeviceStatus(self)
            # TODO set up thread to poll busy, for now insta-done
            st._finished()
            # update the signals
            self.read()
            return st
    
        def read(self):
            v = self._client.send("get_state")
            self.setpoint.put(v["destination"])
            self.readback.put(v["position"])
            return super().read()
    Blaise Thompson
    @untzag
    @Tillsten yes it can be slow if you need to transfer a relatively large amount of data
    Thomas A Caswell
    @tacaswell
    there are lots of things wrong with that class, but that is enough to make bluesky happy to use the device...
    Blaise Thompson
    @untzag
    our approach is to do data processing on the daemon side, and transfer the smaller processed arrays
    Kyle Sunden
    @ksunden_gitlab

    For a lot of what we have been doing, our sensors are scalar values... That said, we are looking towards array detecteion/cameras.

    I have some ideas, including something I think I saw in Ophyd, which is writing directly to a file on the daemon side for such large detectors (thereby only needing to transmit what is actually displayed in a client application over the RPC)

    Blaise Thompson
    @untzag
    I'll also note that you can use yaq daemons for a subset of your hardware, and use a more direct approach for any really high density information like array detectors
    @tacaswell wow that's super helpful
    Thomas A Caswell
    @tacaswell
    
    In [49]: RE(bp.scan([], ym, -5, 5, 25))                                                                                                                              
    
    
    Transient Scan ID: 8     Time: 2020-04-08 19:22:56
    Persistent Unique Scan ID: '667c5f23-c416-4ee7-9004-86c722454a00'
    New stream: 'primary'
    +-----------+------------+-------------+
    |   seq_num |       time | ym_setpoint |
    +-----------+------------+-------------+
    |         1 | 19:22:56.6 |      -5.000 |
    |         2 | 19:22:56.6 |      -4.583 |
    |         3 | 19:22:56.6 |      -4.167 |
    |         4 | 19:22:56.6 |      -3.750 |
    |         5 | 19:22:56.6 |      -3.333 |
    |         6 | 19:22:56.6 |      -2.917 |
    |         7 | 19:22:56.6 |      -2.500 |
    |         8 | 19:22:56.6 |      -2.083 |
    |         9 | 19:22:56.6 |      -1.667 |
    |        10 | 19:22:56.6 |      -1.250 |
    |        11 | 19:22:56.6 |      -0.833 |
    |        12 | 19:22:56.6 |      -0.417 |
    |        13 | 19:22:56.6 |       0.000 |
    |        14 | 19:22:56.6 |       0.417 |
    |        15 | 19:22:56.6 |       0.833 |
    |        16 | 19:22:56.6 |       1.250 |
    |        17 | 19:22:56.6 |       1.667 |
    |        18 | 19:22:56.6 |       2.083 |
    |        19 | 19:22:56.6 |       2.500 |
    |        20 | 19:22:56.6 |       2.917 |
    |        21 | 19:22:56.6 |       3.333 |
    |        22 | 19:22:56.6 |       3.750 |
    |        23 | 19:22:56.6 |       4.167 |
    |        24 | 19:22:56.6 |       4.583 |
    |        25 | 19:22:56.6 |       5.000 |
    +-----------+------------+-------------+
    generator scan ['667c5f23'] (scan num: 8)
    
    
    
    Out[49]: ('667c5f23-c416-4ee7-9004-86c722454a00',)
    that is a very fast motor :-p
    Till Stensitzki
    @Tillsten
    Some real motors are not much slower :)