lneuhaus / pyrpl

pyrpl turns your RedPitaya into a powerful DSP device, especially suitable as a lockbox in quantum optics experiments.
http://lneuhaus.github.io/pyrpl/
MIT License
140 stars 108 forks source link

out of date API page...(and cool project BTW!) #396

Open gsteele13 opened 4 years ago

gsteele13 commented 4 years ago

Hi,

First, let me say: awesome project! Supercool what you guys have done and that you released it open source!

I've been trying to set up an RP for an undergraduate experiment I run. Frustrated by the default code (1.7 seconds to pull a 134 us trace!) I was put onto your project by Samuel, and it looks like it's exactly what I need (quick pulling of traces to my notebook, possibly streaming at some point...)

I was just sitting down to start doing some coding, but I ran into some pretty out of date example code on the API page:

https://pyrpl.readthedocs.io/en/latest/api.html

I've documented some of my experiences here:

https://github.com/gsteele13/gary-misc-notebooks/blob/master/Trying%20PyRPL.ipynb

I'll start digging into the source itself to look for some examples, but I though I would let you know in the meantime.

Cheers, Gary

gsteele13 commented 4 years ago

Maybe also following up on this, a simple request: I would like to trigger the scope manually and the pull the trace (say even just looking at the input noise).

What is the simplest code I can use for this?

Thanks! Gary

gsteele13 commented 4 years ago

Always nice to answer your own question :)

This seems to be a working solution:

s.input1 = 'in1'
s.input2 = 'in2'
s.decimation = 1024
s.average = False
s.average = True
s.trigger_source = 'immediately'
s._start_acquisition()
sleep(s.duration)
c1,c2 = s._get_curve()

Although I am being naughty and using internal functions. Maybe there is a more official way?

SamuelDeleglise commented 4 years ago

Hi Gary,

Sorry for not responding earlier, the babysitting + remote working organization needs a bit of fine-tuning at the moment...

Indeed, you are using some internal functions, the proper way would be:

s.input1 = 'in1' s.input2 = 'in2' s.decimation = 1024 # or s.duration =0.01 s.average = False s.average = True s.trigger_source = 'immediately' s.single() # the function would not return until acquisition is complete.

s.single_async() for an asynchronous acquisition (the function returns immediately)

Indeed, I see that the documentation would need a refresh on this.

Also, regarding the source code for data acquisition with instruments, we apologize for the lack of clarity. This is mainly because we have tried to maintain compatibility between python2.7 and python 3. In the branch python3-only, that will eventually become the default master branch at some point, the code is probably more readable. In particular we use the python3 support for asynchronous tasks, which avoids a lot of event-loop-callback nightmares. Let me know if you encounter problems with that branch...

By the way, did at least the acquisition work fine with the Graphical User Interface ?

gsteele13 commented 4 years ago

Thanks, this is great!

I'll check out a copy of the python3-only branch and have a look.

In the meantime, I've had some strange things with the scaling, but try out the above I'll post these in a different issue if I still have problems

I haven't tried the GUI yet as I am building my own application-specific gui inside a Jupyter notebook using Bokeh and iPywidgets. (Now that I've learned to use it, Bokeh is great and can handle immediate streaming updates directly in the notebook!)

(I also have a question about disabling the gui, but I'll also post that as a separate issue)

Cheers, Gary

gsteele13 commented 4 years ago

Hmmm...I'm not having so much luck with single()

Here is my code:

s.input1 = 'in1'
s.input2 = 'in2'
s.decimation = 1024 # or s.duration =0.01
s.average = False
s.average = True
s.trigger_source = 'immediately'
s.single()

This never returns (need to restart my kernel...)

If I replace s.single() with my earlier code:

s._start_acquisition()
sleep(s.duration)
c1,c2 = s._get_curve()

then this works fine. (aside from scaling issues, which I'll post in the other issue thread...)

SamuelDeleglise commented 4 years ago

This sounds like a problem with the QT event loop.

What branch are you on and what version of python are you using ?

If this is the bug I have in mind, you should also have many problems with the GUI based operation. Can you try to add the scope module in the main window, configure it to immediately and a short curve duration (such that rolling mode is disabled) then click run_continuous. If nothing happens, then this is it.

gsteele13 commented 4 years ago

I'm current running from a pip installation

Indeed, the GUI runs fine with a long duration, but if I go to a short duration and click run_continuous, then the screen is frozen

SamuelDeleglise commented 4 years ago

WOW pip installation is a fearless move... I am really unsure what version is currently on PyPy.

I believe the bug you are having is fixed in more recent versions on github. Probably the master branch would be OK, otherwise, the most up-to-date ones are develop0.9.3 or python3_only.

I strongly advise to use the github version. In principle, you simply need to add the local directory of the repository to your PYTHONPATH environment variable, and I believe it should work out of the box (be careful to properly remove the installation that was in your python distribution to avoid confusion in which code is being executed)

If it is true that the pip version has such a big bug, we will try to quickly create a new release (I hope Leo can help with that because I haven't done that in a long time)

lneuhaus commented 4 years ago

Thanks Gary for pointing this out.

Conclusion here:

The Qt event loop issues are a nightmare in my opinion. The fact that Gary prefers to use low-level scope readout methods is a symptom of that (I have done the same in the past when trying to operate pyrpl with multiple threads, since Qt forbids to send signals to different threads).

Both the need to require a display for starting even in headless mode, and the need to run the application single-threaded are big arguments against Qt in my opinion. Finally, Qt is becoming more and more commercial (despite apparently being unable to drop open source core libraries due to legal issues) and makes life harder for people like us. In fact, a Qt employee confirmed to me that "Qt is not cool any more" ;). I would not mind to move towards a bokeh GUI in the long term.

lneuhaus commented 4 years ago

@gsteele13 just went through your notebook. Must have been a frustrating experience. Thanks a lot for the feedback. I know pyrpl is in a bad state since I had not time to keep it up to date for a long time now, but didnt know it was that bad to a beginner. I'll make sure to pour 1-2 weeks of time into this asap.

gsteele13 commented 4 years ago

No problem! Took me some poking around but I managed in the end. I find it not any worse that the RP SCPI docs (which are also scant). And the performance is WAY better than the RP SCPI :)

BTW, happy to help in any capacity that I can (right now, I've got a reasonable amount of time with corona, fortunately have my RP in attic :))

aadiyatul commented 4 years ago

Actually this issue seems to appear for all the branches master, develop-0.9.3, and python3-only.

What is more interesting, something blocks result() from being set in the same code section. If one runs a code section like this:

s = r.scope
s.input1 = 'in1'
s.decimation = 1024
s.average = False
s.trigger_source = 'immediately'

res = s.single_async()
sleep (0.3)
print("Curve ready:", s.curve_ready())
res.result()

then result() will not be set:

Curve ready: True
Traceback (most recent call last):

  File "<ipython-input-7-2361bd3d13ed>", line 9, in <module>
    res.result()

InvalidStateError: Result is not set.

However, if after that I run from a console or another section

res.result()

it will succeed:

array([[-0.02087402, -0.01904297, -0.02075195, ..., -0.01989746,
        -0.01989746, -0.02026367],
       [-0.01098633, -0.01123047, -0.01196289, ..., -0.01269531,
        -0.01208496, -0.01293945]])
LaserLurch commented 4 years ago

I am having the same problems as aadiyatul and gsteele13. I dowonloaded the pyrpl repository from GitHub and installed it following the instructions on https://pyrpl.readthedocs.io/en/latest/installation.html. Essentially I just want to implement a simple PID Controller, but first i would like to read out the frequency of the Input Signal from the spectrum analyzer. But unfortunately when I call for the curve using the following Code snippet from the API page, the kernel freezes completely and I have to Restart it. ch1, ch2, cross_re, cross_im = p.spectrumanalyzer.curve()

This is strange since the spectrum analyzer in the GUI works fine.

gsteele13 commented 3 years ago

I would not mind to move towards a bokeh GUI in the long term

Some inspiration code: A scope and spectrum analyzer with Live plotting using Bokeh in a notebook:

https://gitlab.tudelft.nl/gsteele/red-pitaya-control-notebooks

and a video demo :)

Red Pitaya with Live Plotting in Jupyter Notebooks

Bruyant commented 3 years ago

Same problem here, i would be happy to work on it!

If this is the bug I have in mind, you should also have many problems with the GUI based operation. Can you try to add the scope module in the main window, configure it to immediately and a short curve duration (such that rolling mode is disabled) then click run_continuous. If nothing happens, then this is it.

Any clue were to look ? at Qt event loop ?