Git Product home page Git Product logo

wand's People

Contributors

bazavano avatar bnichol avatar cjbe avatar dnadlinger avatar hartytp avatar jammyl avatar timboski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wand's Issues

hide reference

Currently, it is very easy to change the frequency reference for a channel. Accidental changes do happen, especially as the exposure time next to it sometimes has to be changed.

Hide in a context menu? Or have a tick box to enable editing?

clients should not die when a server restarts

When the server dies, the gui quits with the message

WARNING:quamash.QEventLoop:Event callback failed: [WinError 64] The specified ne
twork name is no longer available
WARNING:quamash.QEventLoop:Event callback failed: [WinError 64] The specified ne
twork name is no longer available
WARNING:quamash.QEventLoop:Event callback failed: [WinError 64] The specified ne
twork name is no longer available
WARNING:quamash.QEventLoop:Event callback failed: [WinError 64] The specified ne
twork name is no longer available
WARNING:quamash.QEventLoop:Event callback failed: [WinError 64] The specified ne
twork name is no longer available
WARNING:quamash.QEventLoop:Event callback failed: [WinError 64] The specified ne
twork name is no longer available
WARNING:quamash.QEventLoop:Event callback failed: [WinError 64] The specified ne
twork name is no longer available
WARNING:quamash.QEventLoop:Event callback failed: [WinError 64] The specified ne
twork name is no longer available
WARNING:quamash.QEventLoop:Event callback failed: [WinError 64] The specified ne
twork name is no longer available
WARNING:quamash.QEventLoop:Event callback failed: [WinError 64] The specified ne
twork name is no longer available
WARNING:quamash.QEventLoop:Event callback failed: [WinError 64] The specified ne
twork name is no longer available
WARNING:quamash.QEventLoop:Event callback failed: [WinError 64] The specified ne
twork name is no longer available
WARNING:quamash.QEventLoop:Event callback failed: [WinError 64] The specified ne
twork name is no longer available
WARNING:quamash.QEventLoop:Event callback failed: [WinError 64] The specified ne
twork name is no longer available
WARNING:quamash.QEventLoop:Event callback failed: [WinError 64] The specified ne
twork name is no longer available
WARNING:quamash.QEventLoop:Event callback failed: [WinError 64] The specified ne
twork name is no longer available
WARNING:quamash.QEventLoop:Event callback failed: [WinError 64] The specified ne
twork name is no longer available
ERROR:wand.frontend.wand_gui:Connection to server 'lab3' lost, closing
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\windows_events.py",
 line 437, in finish_recv
    return ov.getresult()
OSError: [WinError 64] The specified network name is no longer available

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\tasks.py", line 240
, in _step
    result = coro.send(None)
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\site-packages\artiq\protoco
ls\sync_struct.py", line 88, in close
    await asyncio.wait_for(self.receive_task, None)
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\tasks.py", line 387
, in wait_for
    return (yield from fut)
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\futures.py", line 3
83, in __iter__
    return self.result()  # May raise too.
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\futures.py", line 2
94, in result
    raise self._exception
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\tasks.py", line 242
, in _step
    result = coro.throw(exc)
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\site-packages\artiq\protoco
ls\sync_struct.py", line 100, in _receive_cr
    line = await self.reader.readline()
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\streams.py", line 4
82, in readline
    line = yield from self.readuntil(sep)
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\streams.py", line 5
75, in readuntil
    yield from self._wait_for_data('readuntil')
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\streams.py", line 4
58, in _wait_for_data
    yield from self._waiter
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\futures.py", line 3
81, in __iter__
    yield self  # This tells Task to wait for completion.
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\tasks.py", line 310
, in _wakeup
    future.result()
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\futures.py", line 2
94, in result
    raise self._exception
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\proactor_events.py"
, line 189, in _loop_reading
    data = fut.result()  # deliver data later in "finally" clause
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\futures.py", line 2
94, in result
    raise self._exception
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\site-packages\quamash-0.5.5
-py3.6.egg\quamash\_windows.py", line 41, in _process_events
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\windows_events.py",
 line 440, in finish_recv
    raise ConnectionResetError(*exc.args)
ConnectionResetError: [WinError 64] The specified network name is no longer avai
lable
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\windows_events.py",
 line 437, in finish_recv
    return ov.getresult()
OSError: [WinError 64] The specified network name is no longer available

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\tasks.py", line 240
, in _step
    result = coro.send(None)
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\site-packages\artiq\protoco
ls\sync_struct.py", line 88, in close
    await asyncio.wait_for(self.receive_task, None)
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\tasks.py", line 387
, in wait_for
    return (yield from fut)
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\futures.py", line 3
83, in __iter__
    return self.result()  # May raise too.
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\futures.py", line 2
94, in result
    raise self._exception
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\tasks.py", line 242
, in _step
    result = coro.throw(exc)
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\site-packages\artiq\protoco
ls\sync_struct.py", line 100, in _receive_cr
    line = await self.reader.readline()
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\streams.py", line 4
82, in readline
    line = yield from self.readuntil(sep)
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\streams.py", line 5
75, in readuntil
    yield from self._wait_for_data('readuntil')
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\streams.py", line 4
58, in _wait_for_data
    yield from self._waiter
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\futures.py", line 3
81, in __iter__
    yield self  # This tells Task to wait for completion.
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\tasks.py", line 310
, in _wakeup
    future.result()
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\futures.py", line 2
94, in result
    raise self._exception
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\proactor_events.py"
, line 189, in _loop_reading
    data = fut.result()  # deliver data later in "finally" clause
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\futures.py", line 2
94, in result
    raise self._exception
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\site-packages\quamash-0.5.5
-py3.6.egg\quamash\_windows.py", line 41, in _process_events
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\windows_events.py",
 line 440, in finish_recv
    raise ConnectionResetError(*exc.args)
ConnectionResetError: [WinError 64] The specified network name is no longer avai
lable
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\site-packages\artiq\protoco
ls\pc_rpc.py", line 246, in close_rpc
    self.__writer.close()
AttributeError: 'NoneType' object has no attribute 'close'
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\windows_events.py",
 line 437, in finish_recv
    return ov.getresult()
OSError: [WinError 64] The specified network name is no longer available

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\tasks.py", line 240
, in _step
    result = coro.send(None)
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\site-packages\artiq\protoco
ls\sync_struct.py", line 88, in close
    await asyncio.wait_for(self.receive_task, None)
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\tasks.py", line 387
, in wait_for
    return (yield from fut)
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\futures.py", line 3
83, in __iter__
    return self.result()  # May raise too.
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\futures.py", line 2
94, in result
    raise self._exception
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\tasks.py", line 242
, in _step
    result = coro.throw(exc)
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\site-packages\artiq\protoco
ls\sync_struct.py", line 100, in _receive_cr
    line = await self.reader.readline()
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\streams.py", line 4
82, in readline
    line = yield from self.readuntil(sep)
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\streams.py", line 5
75, in readuntil
    yield from self._wait_for_data('readuntil')
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\streams.py", line 4
58, in _wait_for_data
    yield from self._waiter
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\futures.py", line 3
81, in __iter__
    yield self  # This tells Task to wait for completion.
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\tasks.py", line 310
, in _wakeup
    future.result()
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\futures.py", line 2
94, in result
    raise self._exception
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\proactor_events.py"
, line 189, in _loop_reading
    data = fut.result()  # deliver data later in "finally" clause
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\futures.py", line 2
94, in result
    raise self._exception
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\site-packages\quamash-0.5.5
-py3.6.egg\quamash\_windows.py", line 41, in _process_events
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\asyncio\windows_events.py",
 line 440, in finish_recv
    raise ConnectionResetError(*exc.args)
ConnectionResetError: [WinError 64] The specified network name is no longer avai
lable
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "C:\Users\localadmin\Anaconda3\envs\artiq\lib\site-packages\artiq\protoco
ls\pc_rpc.py", line 246, in close_rpc
    self.__writer.close()
AttributeError: 'NoneType' object has no attribute 'close'

fast mode time out

fast mode should automatically disable itself after some specified amount of time. Otherwise too easy to leave it on and knacker the switch.

Modularize OSA component

Right now we don't have any OSAs. When we do get them we plan on using a Stabilizer board instead of an NI card to scan them and acquire the PD signal.

By breaking out the OSA stuff into its own module (or whatever) we would first be able to install and run unmodified WAND without all the NI dependencies. Then when the time comes we'd be able to write a new OSA module for the stabilizer.

I haven't looked at the code carefully so I'll leave it to @aquinn2 and @Jemetzner to suggest an implementation.

At some point it may be worth doing for the wavemeter too. Some groups use the Bristol ones for example. There is also the issue that High Finesse have just randomly changed the API over the years without documenting so code is only works for some range of serial numbers (though that could be handled by polling the wavemeter for it's model and serial number).

tidy up hf hacks

I've given up on debugging the shitty High Finesse SDK with their engineers. It does not work correctly on some of our older WLMs and it's never going to. So, promote the hacks (e.g. catching the wavemeters deciding not to trigger occasionally) to being part of the "expected" behaviour of the SDK and tidy up

Multi-mode laser detection

Since the DL pros usually don't tend to go multimode on their own, it might take a while to notice when they in fact are – especially when using the wavemeter inteferometer spectra instead of a separate OSA, as they are visually more crowded.

Integrating an algorithm to detect this from the wavemeter CCD images and flag the issue to the user (yellow stripes in the UI background, status queryable via the RPC interface) might be useful. From my own experience, this is definitely possible by eye after staring at the HighFinesse software for long enough, at least for lasers that are grossly multi-mode.

There was some work on this at ETH, though I haven't heard any news as to how well this works in practice: https://ethz.ch/content/dam/ethz/special-interest/phys/quantum-electronics/tiqi-dam/documents/masters_theses/Masterthesis_C%C3%A9dric_Huber

min exposure

currently wand doesn't allow 0ms exposures, while the HF software does. In the source I see the following somewhat cryptic statement. @cjbe @dnadlinger any ideas what the issue was here? Otherwise I'll try removing it and see what breaks

# fix me: setting exp 2 to exp_min gives errors. Works fine via the GUI
if self._exp_min[1] == 0:
self._exp_min[1] = 2

calibration

Add calibration to server and gui. Maybe a context menu on the gui that allows one to calibrate the wlm based on a certain channel?

locker

locking with claim_ownership=False does not release ownership correctly (or did I already fix this?)

[rfc] - WAND lock control loop gain

After reviewing the lock method code have discovered that the control loop has the gain set by the product of the set gain and the poll time. This would seem to suggest this is a integrative term, but would only seem to make sense in the limit of a very slowly converging lock.

I have calibrated our laser controllers to get a proper gain factor and turned this control loop into a simple proportional term by removing this poll time factor. We were hoping that there might be some clarification for why this was the method that was used and if there is a interest to improve the lock to make a proper integrator term.

clean up

have a look at things like the tools and see if we can tidy up a little.

Remove oxford specific bits.

document

  • installation
  • launching
  • high-level overview/block diagram/what problems does this solve
  • how the scheduler works
  • notifier/rpc interfaces
  • hardware

Support for wavemeter lock

I am trying to get the wavemeter lock working and was hoping there could be some documentation on how the lock works. There does not appear to be a way to turn the lock on or off from the GUI. Is there a reason for this or am I missing a way to turn the lock on and off easily?

DLPro interface blocks

Currently we don't use an asyncio interface (e.g. the Toptica SDK) for the DLPros. So, if a lock task tries to connect to an unavailable DLPro controller, that can block the entire server. e.g. if the controller crashes and becomes unresponsive so we get stuck waiting for a connection timeout.

gui crash on server restart

If a server dies while the GUI client is mid-way through establishing a connection, the GUI sometimes crashes. This seems to be non-deterministic and is most likely a race condition somewhere.

It's a bit hard to debug, since I haven't been able to get a proper traceback.

It appears that a ConnectionReset error is raised in asyncio.windows_events.IocpProactor.recv.finish_recv. This leads to asuncio.Future.set_exception being called (via _OverlappedFuture), however the future's state is already _CANCELLED, so an InvalidStateError is raised and the program terminated.

I did try hacking some print(traceback.print_exc())s into the local copy of asyncio in various places, but that always prints None. Not totally sure why.

As part of debugging this, I stripped the GUI down until the only asyncio tasks (asside from QT) are hooking up some sync_struct Subscribers with disconnect_cb hooked up to a trivial function that waits 10s before reconnecting (see below). I can't see any obvious way that my code could be responsible for these symtoms, so I suspect that it's a race condition somewhere in asyncio or quamash. It probably doesn't happen on Linux...

     def subscriber_reconnect_cb(self, server, db):
            print("cb")
            print(traceback.print_exc())
            subscriber, fut = self.subscribers[server][db]
            try:
                fut = asyncio.ensure_future(
                    subscriber_reconnect_coro(self, server, db))
            except Exception as e:
                print(e)
            self.subscribers[server][db] = subscriber, fut

        async def subscriber_reconnect_coro(self, server, db):
            try:
                if self.win.exit_request.is_set():
                    for display in self.laser_displays:
                        display.wake_loop.set()
                    return
            except Exception as e:
                print(e)

            logger.error("No connection to server '{}'".format(server))

            for _, display in self.laser_displays.items():
                if display.server == server:
                    display.server = ""
                    display.wake_loop.set()

            server_cfg = self.config["servers"][server]
            subscriber, fut = self.subscribers[server][db]

            try:
                await subscriber.close()
            except:
                pass

            subscriber.disconnect_cb = functools.partial(
                subscriber_reconnect_cb, self, server, db)

            while not self.win.exit_request.is_set():
                try:
                    print("connecting")
                    await subscriber.connect(server_cfg["host"],
                                             server_cfg["notify"])
                    print("done!")
                    logger.info("Reconnected to server '{}'".format(server))
                    break
                except (ConnectionRefusedError, OSError, ConnectionResetError):
                    pass
                except:
                    logger.info("could not connect to '{}' retry in 10s..."
                                .format(server))
                    await asyncio.sleep(10)
            print("cb complete!")

        for server, server_cfg in self.config["servers"].items():
            self.subscribers[server] = {}

            #ask the servers to keep us updated with changes to laser settings
            # (exposures, references, etc)
            subscriber = Subscriber(
                "laser_db",
                functools.partial(init_cb, self.laser_db),
                functools.partial(self.notifier_cb, "laser_db", server),
                disconnect_cb=functools.partial(
                    subscriber_reconnect_cb, self, server, "laser_db"))
            self.subscribers[server]["laser_db"] = subscriber, None
            subscriber_reconnect_cb(self, server, "laser_db")

            # ask the servers to keep us updated with the latest frequency data
            subscriber = Subscriber(
                "freq_db",
                functools.partial(init_cb, self.freq_db),
                functools.partial(self.notifier_cb, "freq_db", server),
                disconnect_cb=functools.partial(
                    subscriber_reconnect_cb, self, server, "freq_db"))
            self.subscribers[server]["freq_db"] = subscriber, None
            subscriber_reconnect_cb(self, server, "freq_db")

            # ask the servers to keep us updated with the latest osa traces
            subscriber = Subscriber(
                "osa_db",
                functools.partial(init_cb, self.osa_db),
                functools.partial(self.notifier_cb, "osa_db", server),
                disconnect_cb=functools.partial(
                    subscriber_reconnect_cb, self, server, "osa_db"))
            self.subscribers[server]["osa_db"] = subscriber, None
            subscriber_reconnect_cb(self, server, "osa_db")

offset lock

might be interesting to play with offset locks in the wavemeter.

lock one laser to a cavity as a frequency reference, lock another to the wavemeter (or just use a HeNe)
measure both frequencies on each wavemeter lock iteration
adjust the wavemeter lock set-point based on the measured detuning of the laser locked to the cavity
probably not necessary for new wavemeters, which have a HeNe inside for calibration...

sever multi-threading

the list-of-dictionaries approach to multi-threading on the server is a slightly fragile hack. Worth implementing somethign better here.

WLM error handling

Currently, we return a frequency of -1 in case of WLM errors. What's the best python equivalent of a Rust enum? Maybe have the get frequency command return a tuple of status (enum: {ok, under exposed, over exposed, etc}). and value?

[rfc] - Adding OSA driver to config and wavemeter lock clarification

After building a drive to run the setup we are using here at the Oregon we though it might be useful to add the ability to just specify the OSA driver in the server configuration instead of having to hard code it in. This would allow for any OSA setup to be easily supported.

I am also trying to get the wavemeter lock working and was hoping there could be some documentation on how the lock works. There does not appear to be a way to turn the lock on or off from the GUI. Is there a reason for this or am I missing a way to turn the lock on and off easily.

Auto exposure should be off when no laser detected

At the moment, exposure is increased automatically even when no laser input is detected on a channel. This causes lag every time that channel is measured by the wavemeter. Exposure should not be changed when no laser is detected.

wand crashing when window resized

WARNING:wand.tools:Unable to find server configuration file, restoring from backup
Traceback (most recent call last):
  File "C:\Users\ThomasHarty\miniconda3\envs\wand\lib\site-packages\pyqtgraph\widgets\VerticalLabel.py", line 52, in paintEvent
    self.hint = p.drawText(rgn, align, self.text())
TypeError: arguments did not match any overloaded call:
  drawText(self, Union[QPointF, QPoint], str): argument 1 has unexpected type 'QRect'
  drawText(self, QRectF, int, str): argument 1 has unexpected type 'QRect'
  drawText(self, QRect, int, str): argument 2 has unexpected type 'Alignment'
  drawText(self, QRectF, str, option: QTextOption = QTextOption()): argument 1 has unexpected type 'QRect'
  drawText(self, QPoint, str): argument 1 has unexpected type 'QRect'
  drawText(self, int, int, int, int, int, str): argument 1 has unexpected type 'QRect'
  drawText(self, int, int, str): argument 1 has unexpected type 'QRect'
Traceback (most recent call last):
  File "C:\Users\ThomasHarty\miniconda3\envs\wand\lib\site-packages\pyqtgraph\widgets\VerticalLabel.py", line 52, in paintEvent
    self.hint = p.drawText(rgn, align, self.text())
TypeError: arguments did not match any overloaded call:
  drawText(self, Union[QPointF, QPoint], str): argument 1 has unexpected type 'QRect'
  drawText(self, QRectF, int, str): argument 1 has unexpected type 'QRect'
  drawText(self, QRect, int, str): argument 2 has unexpected type 'Alignment'
  drawText(self, QRectF, str, option: QTextOption = QTextOption()): argument 1 has unexpected type 'QRect'
  drawText(self, QPoint, str): argument 1 has unexpected type 'QRect'
  drawText(self, int, int, int, int, int, str): argument 1 has unexpected type 'QRect'
  drawText(self, int, int, str): argument 1 has unexpected type 'QRect'
Traceback (most recent call last):
  File "C:\Users\ThomasHarty\miniconda3\envs\wand\lib\site-packages\pyqtgraph\widgets\VerticalLabel.py", line 52, in paintEvent
    self.hint = p.drawText(rgn, align, self.text())
TypeError: arguments did not match any overloaded call:
  drawText(self, Union[QPointF, QPoint], str): argument 1 has unexpected type 'QRect'
  drawText(self, QRectF, int, str): argument 1 has unexpected type 'QRect'
  drawText(self, QRect, int, str): argument 2 has unexpected type 'Alignment'
  drawText(self, QRectF, str, option: QTextOption = QTextOption()): argument 1 has unexpected type 'QRect'
  drawText(self, QPoint, str): argument 1 has unexpected type 'QRect'
  drawText(self, int, int, int, int, int, str): argument 1 has unexpected type 'QRect'
  drawText(self, int, int, str): argument 1 has unexpected type 'QRect'
Traceback (most recent call last):
  File "C:\Users\ThomasHarty\miniconda3\envs\wand\lib\site-packages\pyqtgraph\widgets\VerticalLabel.py", line 52, in paintEvent
    self.hint = p.drawText(rgn, align, self.text())
TypeError: arguments did not match any overloaded call:
  drawText(self, Union[QPointF, QPoint], str): argument 1 has unexpected type 'QRect'
  drawText(self, QRectF, int, str): argument 1 has unexpected type 'QRect'
  drawText(self, QRect, int, str): argument 2 has unexpected type 'Alignment'
  drawText(self, QRectF, str, option: QTextOption = QTextOption()): argument 1 has unexpected type 'QRect'
  drawText(self, QPoint, str): argument 1 has unexpected type 'QRect'
  drawText(self, int, int, int, int, int, str): argument 1 has unexpected type 'QRect'
  drawText(self, int, int, str): argument 1 has unexpected type 'QRect'
Traceback (most recent call last):
  File "C:\Users\ThomasHarty\miniconda3\envs\wand\lib\site-packages\pyqtgraph\widgets\VerticalLabel.py", line 52, in paintEvent
    self.hint = p.drawText(rgn, align, self.text())
TypeError: arguments did not match any overloaded call:
  drawText(self, Union[QPointF, QPoint], str): argument 1 has unexpected type 'QRect'
  drawText(self, QRectF, int, str): argument 1 has unexpected type 'QRect'
  drawText(self, QRect, int, str): argument 2 has unexpected type 'Alignment'
  drawText(self, QRectF, str, option: QTextOption = QTextOption()): argument 1 has unexpected type 'QRect'
  drawText(self, QPoint, str): argument 1 has unexpected type 'QRect'
  drawText(self, int, int, int, int, int, str): argument 1 has unexpected type 'QRect'
  drawText(self, int, int, str): argument 1 has unexpected type 'QRect'
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QBackingStore::endPaint() called with active painter; did you forget to destroy it or call QPainter::end() on it?
QPaintDevice: Cannot destroy paint device that is being painted

Query Frequency Indexing Error

We have encounterd a TypeError when executing the code coming from this line on the gui.py code. It seems the databases is not being indexed properly without this additional call.
freq = self._gui.freq_db[self.laser]["freq"] -> freq = self._gui.freq_db[self.laser][0]["freq"]

I don't understand the exposures on the lab II WLM!

another delightful "feature" from high finesse:

When the WLM is operated in "switch mode" the exposure settings behave differently both in the SDK and the GUI. The interference traces for a given exposure are different (usually higher peaks with the switch mode). The second interferometer height doesn't seem to change with exposure time between 0ms and 600ms! I think the second interferometer setting is ignored?

For now, I'm disabling auto exposure in lab 2...

possible race condition in the gui updates

This needs a little more thought. Currently:

  • on gui state chage, we send an async (non-blocking) RPC to the server to request it to update its state
  • before receiving a response from the server we update our local copy of the status db (laser_db) (can't remember why we do this)
  • however, the server does not necessarily execute all requested state changes if there is a backlog; it only executes the most recent one.
  • are there corner cases here that can lead to corrupt state on the GUI?

wand_gui doesn’t run properly with python3.8

When running the wand_gui with python3.8, the gui does not update when using any of the gui operations (eg fast mode). However, the gui receives updates when other clients (using other py versions) have the fast mode selected, for example.

Debugging in wand\gui.py:
The fast mode button works:
print(data) in add_async_cb gives ('fast_mode',)
however this doesn’t reach fast_mode_cb

print(self.fut.done()) is True in add_async_cb. However, print(self.fut.result()) in add_async_cb gives the following error:
File "/home/ion/scratch/wand_new/wand/gui.py", line 123, in add_async_cb
    print(self.fut.result())
  File "/home/ion/scratch/wand_new/wand/gui.py", line 300, in loop
    await asyncio.wait_for(self.wake_loop.wait(),
  File "/home/ion/anaconda3/envs/wand_py38/lib/python3.8/asyncio/tasks.py", line 448, in wait_for
    loop = events.get_running_loop()
RuntimeError: no running event loop

Increase wlm timeout

From current 1s to slightly over the wlm max exposure. Currently exposures above 1s lead to timeouts

breakage with recent PyQt5

We import our widgets from PyQt5.QtGui

from PyQt5 import QtGui
self.f_ref = QtGui.QDoubleSpinBox()

Running with the latest PyQtGraph we get errors like AttributeError: module 'PyQt5.QtGui' has no attribute 'QCheckBox'

Looking at the docs it seems like the path should be PyQt5.QWidgets.

I wonder if we can do something like

try:
    from PyQt5 import QtWidgets
except ImportError:
    from PyQt5 import QtGui

clean up locker

it's currently a proof-of-concept that worked well enough for no one to bother improving it.

  • Interface is a bit clunky and needs tidying up
  • add lock status/ownership to GUI
  • update lock loop immediately on parameter change (otherwise a bit of a pain when the lock update time is slow)

[rfc] - Adding OSA driver to config file

After building a driver to run the setup we are using here at the Oregon we though it might be useful to add the ability to just specify the OSA driver in the server configuration instead of having to hard code it in. This would allow for any OSA setup to be easily supported.

Tidy up publisher/subscriber interface

Was written as a learning exercise and could do with a clean up (e.g. scrap the laser_sup_db hacks). While we're at it, it might be worth considering using something like zeromq to distribute the OSA traces (fewer issues with slow internet connections to clients)

server should store poll times

currently, each GUI has its own poll time. This means that whichever GUI has the shortest poll time determines the actual update rate. It would be better if the server stored the poll times (don't need to be settable via RPC, just command line should be fine).

server conda build

doesn't work as it doesn't have a package for pydaqmx, so I'm pip installing into artiq-env on the servers. If we can be bothered then we could package pydaqmx and then fix the server build.

Fix WLM exposures

Currently we only set the exposure on CCD1. We should set it on both CCDs.

While we're at it, we should probably add an auto-exposure feature. e.g. each time we read a wavelength, pull in the CCD trace and look at the peak heights. Then increment/decrement the exposures if the peak height is outside some fixed range.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.