-
Notifications
You must be signed in to change notification settings - Fork 320
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
Feature/parameter node, change parameter get/set behaviour #935
Feature/parameter node, change parameter get/set behaviour #935
Conversation
@nulinspiratie, on behalf of the Copenhagen devs: We certainly appreciate your effort, but need to raise a few words of caution. Even without having looked at the code in any detail, learning from our experience with our last big change to the parameters, where we had to clean up and hotfix for months after merging, there is no way such a fundamentally changing PR can be merged in one go. Changing the API of The above entails that the new The work flow would be something like:
This may seem like an unfulfilling snail pace to you, but we have a large user groups whose day-to-day work depends on QCoDeS. |
@WilliamHPNielsen Thanks for your reply. I definitely agree that this would be a significant change, and would break compatibility, which is a big issue affecting many users. I wasn't expecting this to be merged any time soon, if at all. However, It's something our fork will probably switch to, and I thought I'd place it here as a potential future direction for parameters (QEP does sound nice!). |
Hi Serwan, cool that you guys are still innovating on your QCoDeS fork! I personally do not like the change in the get/set behaviour. I think there were good reasons why it is implemented the way it is and to be honest I personally think the way that part works is really solid and should not be changed. Another item (as mentioned by @WilliamHPNielsen ) is the potentially breaking backwards compatibility . I am paranoid about those and for me that is the chief reason that sometimes delays updates and creates diverging branches/forks, something which should be avoided in my opinion. I do think a first implementation of the parameter node is cool and potentially very useful, though I do not understand why you changed the inheritance for the base instrument. I also like your example notebook but I would like to have some more detail in there, mostly to see how it support the I am afraid that in it's current form the node-tree functionality get's buried in the alternative get/set behaviour. I do think it is great as a conversation starter though :). |
Hey @AdriaanRol thanks for the useful comments. I definitely see your point that the get/set behaviour works well for Instruments, especially because it makes explicit when VISA commands are communicated with the physical instrument. I've made some changes to the ParameterNode that keeps this behaviour and may be a good middle way (see below). The reason why I removed the instrument inheritance from @WilliamHPNielsen Breaking backwards compatibility is definitely an issue, and I've been thinking how to deal with it. I think I've found a solution that works, namely by adding the flag Setting
|
Codecov Report
@@ Coverage Diff @@
## master #935 +/- ##
==========================================
+ Coverage 67.21% 77.14% +9.93%
==========================================
Files 145 38 -107
Lines 17951 5289 -12662
==========================================
- Hits 12065 4080 -7985
+ Misses 5886 1209 -4677 |
@WilliamHPNielsen @jenshnielsen Do you think this PR has a shot at being accepted? I understand the hesitancy to change core functionalities, but I do think the change wouldn't cause breaking changes. I've purposely left the old usage intact, and added functionality on top of it. This means that all the drivers etc. should still work as is. The tests are basically passing (one sometimes fails, but seems unrelated to this PR), and I think it would add an avenue to integrate Parameters more easily into classes that are unrelated to Instruments. If not, then we can close this PR. |
This PR proposes to add the ParameterNode, as raised by @AdriaanRol in #773. My main goal was to have a different way of setting/getting parameters instead of using brackets (raised in #767). I've added a tutorial on how to use the ParameterNode in the PR.
Changes proposed in this pull request:
The proposed new method is:
parameter_node.parameter = 42
parameter_node.parameter
(returns 42)These commands set/get the value of the parameter, and the underlying parameter is accessed differently (see below for details).
Note that the parameter get/set itself isn't changed, if you have a parameter object, you should still use brackets.
I think the main advantage of the new get/set method is that one doesn't need to think if an attribute is actually a Parameter or not. This allows you to replace attributes with parameters as you see fit, while also being able to keep other attributes the way they are. Having parameters behave as attributes also feels more pythonic IMHO.
One potential issue with this new method is that any time a parameter attribute is accessed, this will cause a
.get()
, therefore,hasattr(parameter_node, 'parameter')
will call its.get
method. I'm not sure if this is an issue, as there aren't many cases where this happens.Smaller changes
print_readable_snapshot
withprint_snapshot
, the snapshot being readable should be a given.I haven't implemented everything discussed in #773, I first wanted to get some thoughts on the new proposed method
Below is a summary of the ParameterNode, this is explained in more detail in the added tutorial notebook
Creating a ParameterNode
Parameter nodes are instantiated via:
parameter_node = ParameterNode()
Adding parameters
parameters can be added by setting an attribute:
parameter_node.new_parameter = Parameter()
Note that it is no longer necessary to specify a name in the Parameter. If it is not explicitly specified, it will be set to the attribute name
Getting/setting parameter values
Getting and setting of parameters in a parameter node is now done same as you would any other attribute:
parameter_node.new_parameter = 42
parameter_node.new_parameter
(returns 42)Accessing parameter object
The actual parameter can be accessed in two ways:
parameter_node.parameters.new_parameter
(parameter_node.parameters
is aDotDict
).parameter_node().new_parameter
, the call()
will returnparameter_node.parameters
.The second method is more succinct, but does have one drawback, namely that autocomplete won't work with it. I haven't figured out another way of easily accessing parameters that does have autocomplete, or a way to add autocompletion to the call method.
Nesting nodes
Parameter nodes can also be nested, similarly to how parameters are added:
parameter_node.nested_parameter_node = ParameterNode()
.This sets the nested parameter node's name to the attribute.
@AdriaanRol @jenshnielsen @WilliamHPNielsen @giulioungaretti @alexcjohnson @alan-geller @spauka