oxfordiontrapgroup / wand Goto Github PK
View Code? Open in Web Editor NEWWavemeter Analysis aNd Display
License: Other
Wavemeter Analysis aNd Display
License: Other
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?
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 should automatically disable itself after some specified amount of time. Otherwise too easy to leave it on and knacker the switch.
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).
Currently we use a home-brew driver that pre-dates the Toptica SDK. Might be better to scrap ours and switch to the SDK.
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
To do: replace the old school socket interface with a pyserial interface
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
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
wand/wand/drivers/high_finesse.py
Lines 105 to 107 in 1fb4ac4
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?
locking with claim_ownership=False does not release ownership correctly (or did I already fix this?)
Python package directories are not meant to store writable user configuration data.
Quick patch: https://git.m-labs.hk/M-Labs/nix-scripts/src/branch/master/artiq-full/wand-fix-config-dir.patch
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.
have a look at things like the tools
and see if we can tidy up a little.
Remove oxford specific bits.
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?
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.
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")
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...
the list-of-dictionaries approach to multi-threading on the server is a slightly fragile hack. Worth implementing somethign better here.
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?
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.
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.
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
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"]
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...
This needs a little more thought. Currently:
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
From current 1s to slightly over the wlm max exposure. Currently exposures above 1s lead to timeouts
We import our widgets from PyQt5.QtGui
Line 9 in 3987036
Line 65 in 3987036
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
it's currently a proof-of-concept that worked well enough for no one to bother improving it.
now we don't need it for protocols, we can simplify the conda dependencies
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.
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)
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).
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.
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.