-
Notifications
You must be signed in to change notification settings - Fork 95
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Remove length check in ValenceDict #1183
Comments
Sounds good. I thought about this a bit and there's no need to limit it to 4 atoms. Happy to take a PR on this.
I need to think more on this, because I forgot all the details of how this method is used - Is this separable from the other aspects of this issue or are they intertwined for your purposes?
Agree. Happy to take a PR on this. |
They're intertwined because currently the
If you look at the indices you'll notice that they're just the forward (0) and backward (1) permutation, but manually specified so that only index lengths up until 4 are supported. Taking the generic forward/backward would be a general case of the rule. Edit: no, I'm wrong -- and I'm not certain the dihedrals sorting makes sense. If the bonds go A-B-C-D, does it make sense to accept D-B-C-A? Does it not conflict with the |
.index_of appears to only be used in one place: the VirtualSiteHandler. It looks like it calls |
My opinion here is that the ValenceDict class is for MM valence forces: bonds, angles, and torsions, and limits to < 5 because these forms have exactly two symmetries and have concrete orderings. Releasing the limit check makes the dictionary 1. not a valence dictionary anymore and 2. changes the behavior of the class. One should use the SortedDict if one wants to sort an arbitrary key length. What is the use case for a ValenceDict without a bounds check?
Yes this is a mistake and the second form should be 3-2-1-0.
I do stuff like this because a class method would carry around uneeded object state. There is also no dependence on the On a broader level, this implementation was written before |
Sorting isn't quite the same thing as symmetry (forwards/backwards). D-A-B-C-E should match E-C-B-A-D but not A-B-C!-D!-E. As an existing example, what about CMAP torsions? Or anything that is a string of >4 atoms bonded in a chain, where both forwards and backwards matching is ok.
Sorry -- I don't follow, especially what you're saying about serialization. Could you clarify? You're accessing the object state (by this I assume you mean the class, which is technically an object in Python and an instance of In [1]: class Superclass:
...:
...: @staticmethod
...: def is_called():
...: print(f"called from superclass")
...:
...: @staticmethod
...: def caller():
...: print(f"calling method from {__class__}")
...: __class__.is_called()
...:
...:
...: class Subclass(Superclass):
...: @staticmethod
...: def is_called():
...: print("called from subclass")
...:
In [2]: class Subclass2(Subclass):
...: @staticmethod
...: def caller():
...: print(f"calling method from {__class__}")
...: __class__.is_called()
...:
In [3]: Subclass.caller()
calling method from <class '__main__.Superclass'>
called from superclass
In [4]: Subclass2.caller()
calling method from <class '__main__.Subclass2'>
called from subclass The class is necessarily defined ("carried around") whenever you call a method belonging to that class because, well, you're calling it from the class. Making it a |
I don't disagree here but I don't see how it fits into the discussion. Are there 5-body valence terms that we need to support?
Use a TagSortedDict or implement a CMAP-specific handler.
Not a valence set and likely more akin to a chemical environment. Perhaps a new
Only
where |
Not currently; that's why this is a feature request instead of a bug report. It seems unnecessarily restrictive to me, given that nothing in the current toolkit needs this check. I can implement my own dictionary, but when all functionality is already present in ValenceDict and the only thing stopping me is an AssertionError, it seems like it'd save users and computer time to just remove the assertion. Making a ChainDict and having ValenceDict subclass that with the assertion is definitely one solution.
That's definitely a valid concern for normal staticmethods -- I was speaking of ones that refer to In [2]: # %load static_test.py
...: #!/usr/bin/env python3
...:
...: import pprint
...: from concurrent.futures import ProcessPoolExecutor
...:
...: class A:
...: class_var = 2
...:
...: @staticmethod
...: def s_meth():
...: __class__.class_var
...: return pprint.pformat(locals())
...:
...: @classmethod
...: def c_meth(cls):
...: cls.class_var
...: return pprint.pformat(locals())
...:
...: if __name__ == "__main__":
...: with ProcessPoolExecutor(1) as pool:
...: print(pool.submit(A.s_meth).result())
...: print(pool.submit(A.c_meth).result())
...:
{'__class__': <class '__main__.A'>}
{'cls': <class '__main__.A'>} |
I am by no means an expert on the subject, so I wouldn't know without testing it. However I don't think that particular case applies to the code in this issue. I see a PR has already been crafted to get this change in, so no need for me to get in the way here. Thanks for catching the bug in the ordering! |
ValenceDict and ImproperDict both have staticmethods that use
|
Gotcha, I see some points on both sides but ultimately I agree with @lilyminium on all proposed changes here. This is sorta related to a legacy of rough edges around vsites, which came to be because, when @trevorgokey and I were working on it, vsites were supposed to take like a month, and then at the 6 month point, when crazy edge cases kept popping up, and we had unilaterally made changes to the SMIRNOFF spec, and @trevorgokey had rewritten everything several times, we finally said "this is good enough", and this got out with some rough edges. So thanks to both of you for the great discussion, I think @lilyminium's correct-er on every point (except I'm giving up on trying to understand the serialization thing, so I have no opinion there) I've approved the PR that will close this issue. |
Is your feature request related to a problem? Please describe.
ValenceDict has a number of restrictions that require the length of the key to be no more than 4 atoms. Is there a real reason for this?
Describe the solution you'd like
Remove length check here:
openff-toolkit/openff/toolkit/topology/topology.py
Lines 94 to 103 in c32527b
Refactor this to just take the forward or backward permutation. Also, it's much more idiomatic python to make this a classmethod instead of a staticmethod that uses
__class__
.permutations = OrderedDict({refkey: 0, refkey[::-1]:1})
openff-toolkit/openff/toolkit/topology/topology.py
Lines 105 to 165 in c32527b
Describe alternatives you've considered
Additional context
The text was updated successfully, but these errors were encountered: