Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Driver/awg5014 #410

Closed

Conversation

WilliamHPNielsen
Copy link
Contributor

@WilliamHPNielsen WilliamHPNielsen commented Dec 8, 2016

Fix: Make AWG5014 driver less of a bloody mess

Changes proposed in this pull request:

  • Remove some dead methods
  • Add docstrings to all methods
  • Add an example notebook

Changes planned for the near future:

  • Expand example notebook to show how to upload and load .awg files
  • Make SCPI command syntax uniform (use full command strings)
  • Delete more dead methods
  • Refactor a few set/get methods to be parameters
  • Make helper methods to ease the creation of .awg files

@giulioungaretti

No notebook previously documented how to use the AWG driver. More functions are to be added in a later commit.
This commit removes five methods deemed obsolete from the code. The methods either contained python3 incompatible lines or could not work on a general setup. Removing them improves maintainability of the code.
This commit removes the method `set_filename`. The method contained variable names and comments in Dutch, deeming it hard to maintain. Furthermore, the methods overrode the built-in bool type, which is obviously very dangerous.
Subsistute logging.info, logging.warning, and logging.debug for print statements. Remove the use of the protected name `dir` as a variable (call it `folder` instead)..
This change adds a docstring to each and every method of the driver class.
WilliamHPNielsen and others added 9 commits December 9, 2016 11:05
Make all SCPI commands uniform by using the full mixed-case form also found in the manual. This will make searching the driver easier.
Rewrite all old-style string formatting commands ('Foo is %i' % 100) to modern style ('Foo is {}'.format(100))
This commit adds a high-level (easy-to-use) function for making and uploading .awg-files as well as an example notebook documenting how to use it.
This commit removes a handful of methods from the AWG5014 driver and crucially also removes positional arguments from the __init__ function. There are now only two supported ways of uploading waveforms. This is described in the example notebook.

Breaking changes: the __init__ function now only takes two positional arguments, name and address.
This commit changes the sequence length, the reference clock state, the DC output state, and the DC output level for each channel from being methods to QCoDeS parameters.
Copy link
Contributor

@giulioungaretti giulioungaretti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor notes aside LGTM ! Terrific job !

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

import numpy as np
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The imports do not follow pep8 :D

message = self.visa_handle.read()
if verbose:
print(message)
except:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to catch the right exception here!

logging.debug(
__name__ + ' : Sending waveform %s to instrument' % wfmname)
__name__ + ' : Sending waveform {} to instrument'.format(wfmname))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion for logging:
use a module level logger as in here:
https://github.com/QCoDeS/Qcodes/pull/416/files#diff-4c81a52a7bb6d513e5c5cd6c1b1f2c38R11

then all the calls to the logging system will include the module name which allows to tweak logging (say levels and handlers per module ) 👠

Delete all user-defined waveforms in the list in a single
action. Note that there is no “UNDO” action once the waveforms
are deleted. Use caution before issuing this command.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trailing whitespace :P

Copy link
Contributor

@giulioungaretti giulioungaretti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try to check all the returns documentation.

It should look like this:

        Returns:
            dict: A dict with the current setting for each entry in
            AWG_FILE_FORMAT_HEAD iff this entry applies to the AWG5014 AND has
            been changed from its default value.

set_cmd='SEQuence:LENGth ' + '{}',
get_parser=int,
vals=vals.Ints(0, 8000),
docstring=('This command sets the sequence length' +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may want to use a single """ """" string here!


Returns:
str: A ""-encapsulated \n-terminated string with the full path
of the current folder.
Copy link
Contributor

@giulioungaretti giulioungaretti Dec 16, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line should be indented a bit less, else the documentation breaks!
You can check it by running the build doc on your machine as well!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related to what I suggested last week, I would build the docs and ensure than no Sphinx warnings are raised from this file. RST syntax is hard to get right without testing

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


Returns:
str: Either 'HARD' or 'SOFT' indicating that the instrument is in
either hardware or software sequencer mode.
Copy link
Contributor

@giulioungaretti giulioungaretti Dec 16, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above indent less!


Returns:
dict: A dict with the current setting for each entry in
AWG_FILE_FORMAT_HEAD iff this entry applies to the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

Copy link
Contributor

@AdriaanRol AdriaanRol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really like the work you've done, especially all the docstrings. I've mostly checked the initial part.

Most potential for breaking stuff requires testing. I suggest we wait for @CJvanDiepen 's feedback before merging.

@@ -310,29 +337,6 @@ def __init__(self, name, setup_folder, address, reset=False,
vals=vals.Numbers(-2.7, 2.7),
get_parser=float)

# # Add functions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason for removing the add_functions? As far as I understand this is a QCoDeS concept to easily list all the function (that are note parameters) in an instrument.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wondering what happened to this, is the add functions a deprecated qcodes concept?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AdriaanRol commented code was removed, and in many cases the functions where not even defined. So in all effects this particular change is a NOP 🎉

Functions are still there as methods/parameters or as qcodes.functions where it makes sense to @WilliamHPNielsen (and also according to the documentation of the Function class), see line 143.
I would say that many of the comment lines were pretty good candiate for being parameters.
example

# self.add_function('set_event_jump_timing')
# self.add_function('get_event_jump_timing')

became:

        self.add_parameter('event_jump_timing',
                           get_cmd='EVENt:JTIMing?',
                           set_cmd='EVENt:JTIMing {}',
                           vals=vals.Enum('SYNC', 'ASYNC'))

Hope this explains !

@@ -341,328 +345,426 @@ def __init__(self, name, setup_folder, address, reset=False,

# Functions
def get_all(self, update=True):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not remove this (or at least add a depreciation warning) and let people use snapshot(update=True)

Copy link
Contributor Author

@WilliamHPNielsen WilliamHPNielsen Jan 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No good reason. I left it in case of compatibility issues, but I agree that it is a silly wrapper/renaming for a standard function.

A warning has been added.

.replace(',"$', '\n$').replace('","', '\n')
.replace(',', '\t'))
return self.ask('mmem:cat?')
return self.ask('MMEMory:CATalog?')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why query twice? Is it not better to ask it once and then print if print_contents=True

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that is better. I didn't go through all the methods to see if they were smart, so there are probably (quite?) a few blunders left. I'll certainly fix this one.

print('Current AWG file set to: ', self.get_current_folder_name())
self.write('AWGC:SRES "%s.awg"' % fname)

def set_setup_filename(self, fname, force_load=False):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if removing this is a good idea. Knowing about the hardware limitations (writing speed) it is sometimes very convenient to load a sequence that was previously put in memory of the 5014. I think this function can be cleaned up a bit but removing it completely may not be such a good idea.

Copy link
Contributor Author

@WilliamHPNielsen WilliamHPNielsen Jan 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My idea was that it is better to have just one way of doing things. To load an awg file from memory (which is not a stupid thing to do for large files where file transfer times matter), one can/should now use load_awg_file. Do you think that set_setup_filename does something very different than load_awg_file? If so, I would suggest to incorporate that into load_awg_file.

@CJvanDiepen
Copy link
Contributor

@AdriaanRol @WilliamHPNielsen Just tested if the functionality of the AWG driver that we use (the send_waveform_to_list style) still works and it does! Only had to adjust the initialization because the revised driver does not work with a setup_folder anymore. Actually we did not use this but I also do not know if the functionality it offered was important, do any of you know?

@AdriaanRol
Copy link
Contributor

AdriaanRol commented Jan 2, 2017 via email

This commit fixes the issues raised by helpful code reviewers on 2016-12-16.
This commit adds the possibility to select specific channels to upload waveforms to.
This commit changes the logging to a module level logger.
@nataliejpg
Copy link
Contributor

nataliejpg commented Jan 3, 2017

especially love the example notebook, thanks William.

Add a helper function that can parse an awg file and return numpy arrays of waveforms and markers, lists of sequencer information, and a dictionary with instrument settings.
@jenshnielsen jenshnielsen mentioned this pull request Jan 12, 2017
WilliamHPNielsen and others added 15 commits January 17, 2017 09:39
Introduce a parser to fix a newline problem
Fix a problem with newline-termination of instrument return values by adding a parser.
this covers some of the request made years ago.
Because of the design of many pieces of qcodes the code
is really hacky and anti-cool.
Uses empty names and shapes. Will it fix?
Add a parameter for the sequencer position and update the example notebook.

Breaking changes: The two methods get_sq_position and sq_forced_jump no longer exist. Their functionality has been absorbed by the new parameter.
Get in line with the new parameter styles.
@WilliamHPNielsen WilliamHPNielsen deleted the driver/AWG5014 branch February 8, 2017 16:18
@jenshnielsen
Copy link
Collaborator

replaced by #482

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants