"...src/ssh:/git@developer.sourcefind.cn:2222/tsoc/openmm.git" did not exist on "a6cd8c226313161296882e1eb50d5f3aef82e85b"
Unverified Commit c87b96fb authored by Rasmus Wriedt Larsen's avatar Rasmus Wriedt Larsen Committed by GitHub
Browse files

Minor Python tweaks (#2616)

* Use list-comprehension in Python code

A minor change, but slighly easier to understand the initialization of
`parent_exclude_list` in my opinion.

* Implement __ne__ in Python classes that has __eq__

In Python 3, `__ne__` is automatically implemented as `not __eq__`.

However, in Python 2 it seems to be implemented as `not is` (so based on object
identity).

Based on setup.py [0] which says that "OpenMM requires Python 2.7 or better", it
should be useful to have better support for Python 2 :)

This was already done in 4 of the 12 classes that implements `__eq__`

```
>>> class WildCard(object):
...     def __eq__(self, other): return True

>>> w = WildCard()

>>> w == 42
True

>>> w != 42
True

>>> w != w
False
```

[0]: https://github.com/openmm/openmm/blob/5cef29ce8d4e17b6d0f9fd8a3c6cc1669ca0ba2b/wrappers/python/setup.py#L237

* Use umambiguous floor division for index calculations in Python

This makes the code work as intended if run...
parent 691ee619
...@@ -272,7 +272,7 @@ removeType = [False]*len(types) ...@@ -272,7 +272,7 @@ removeType = [False]*len(types)
for res in residueAtoms: for res in residueAtoms:
if res not in residueBonds: if res not in residueBonds:
continue continue
atomBonds = [[] for atom in residueAtoms[res]] atomBonds = [[] for _ in residueAtoms[res]]
for bond in residueBonds[res]: for bond in residueBonds[res]:
atomBonds[bond[0]].append(bond[1]) atomBonds[bond[0]].append(bond[1])
atomBonds[bond[1]].append(bond[0]) atomBonds[bond[1]].append(bond[0])
...@@ -361,7 +361,7 @@ for tor in reversed(torsions): ...@@ -361,7 +361,7 @@ for tor in reversed(torsions):
tag = " <Proper class1=\"%s\" class2=\"%s\" class3=\"%s\" class4=\"%s\"" % signature tag = " <Proper class1=\"%s\" class2=\"%s\" class3=\"%s\" class4=\"%s\"" % signature
i = 4 i = 4
while i < len(tor): while i < len(tor):
index = i/3 index = i//3
periodicity = int(float(tor[i+2])) periodicity = int(float(tor[i+2]))
phase = float(tor[i+1])*math.pi/180.0 phase = float(tor[i+1])*math.pi/180.0
k = tor[i]*4.184 k = tor[i]*4.184
...@@ -380,7 +380,7 @@ for tor in reversed(impropers): ...@@ -380,7 +380,7 @@ for tor in reversed(impropers):
tag = " <Improper class1=\"%s\" class2=\"%s\" class3=\"%s\" class4=\"%s\"" % signature tag = " <Improper class1=\"%s\" class2=\"%s\" class3=\"%s\" class4=\"%s\"" % signature
i = 4 i = 4
while i < len(tor): while i < len(tor):
index = i/3 index = i//3
periodicity = int(float(tor[i+2])) periodicity = int(float(tor[i+2]))
phase = float(tor[i+1])*math.pi/180.0 phase = float(tor[i+1])*math.pi/180.0
k = float(tor[i])*4.184 k = float(tor[i])*4.184
......
...@@ -23,7 +23,7 @@ nbfixes = {} ...@@ -23,7 +23,7 @@ nbfixes = {}
def getFieldPairs(fields): def getFieldPairs(fields):
pairs = [] pairs = []
for i in range(len(fields)/2): for i in range(len(fields)//2):
pairs.append((fields[2*i], fields[2*i+1])) pairs.append((fields[2*i], fields[2*i+1]))
return pairs return pairs
...@@ -361,7 +361,7 @@ print(' <CMAPTorsionForce>') ...@@ -361,7 +361,7 @@ print(' <CMAPTorsionForce>')
for values in sorted(uniqueCmaps, key=lambda x: uniqueCmaps[x]): for values in sorted(uniqueCmaps, key=lambda x: uniqueCmaps[x]):
print(' <Map>') print(' <Map>')
size = int(math.sqrt(len(values))) size = int(math.sqrt(len(values)))
shift = size/2 shift = size//2
scale = kilocalories_per_mole.conversion_factor_to(kilojoules_per_mole) scale = kilocalories_per_mole.conversion_factor_to(kilojoules_per_mole)
# Convert the ordering from the one used by CHARMM to the one used by OpenMM. # Convert the ordering from the one used by CHARMM to the one used by OpenMM.
reordered = [0]*len(values) reordered = [0]*len(values)
......
...@@ -108,15 +108,12 @@ if not release: ...@@ -108,15 +108,12 @@ if not release:
if not IS_RELEASED: if not IS_RELEASED:
full_version += '.dev-' + git_revision[:7] full_version += '.dev-' + git_revision[:7]
a = open(filename, 'w') with open(filename, 'w') as a:
try:
a.write(cnt % {'version': version, a.write(cnt % {'version': version,
'full_version' : full_version, 'full_version' : full_version,
'git_revision' : git_revision, 'git_revision' : git_revision,
'isrelease': str(IS_RELEASED), 'isrelease': str(IS_RELEASED),
'path': os.getenv('OPENMM_LIB_PATH')}) 'path': os.getenv('OPENMM_LIB_PATH')})
finally:
a.close()
def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM, def buildKeywordDictionary(major_version_num=MAJOR_VERSION_NUM,
...@@ -249,5 +246,3 @@ def main(): ...@@ -249,5 +246,3 @@ def main():
if __name__ == '__main__': if __name__ == '__main__':
main() main()
...@@ -1384,9 +1384,7 @@ class CharmmPsfFile(object): ...@@ -1384,9 +1384,7 @@ class CharmmPsfFile(object):
# Add excluded atoms # Add excluded atoms
# Drude and lonepairs will be excluded based on their parent atoms # Drude and lonepairs will be excluded based on their parent atoms
parent_exclude_list=[] parent_exclude_list=[[] for _ in self.atom_list]
for atom in self.atom_list:
parent_exclude_list.append([])
for lpsite in self.lonepair_list: for lpsite in self.lonepair_list:
idx = lpsite[1] idx = lpsite[1]
idxa = lpsite[0] idxa = lpsite[0]
......
...@@ -678,7 +678,7 @@ def readAmberSystem(topology, prmtop_filename=None, prmtop_loader=None, shake=No ...@@ -678,7 +678,7 @@ def readAmberSystem(topology, prmtop_filename=None, prmtop_loader=None, shake=No
if shake in ('all-bonds', 'h-angles'): if shake in ('all-bonds', 'h-angles'):
for (iAtom, jAtom, k, rMin) in prmtop.getBondsNoH(): for (iAtom, jAtom, k, rMin) in prmtop.getBondsNoH():
system.addConstraint(iAtom, jAtom, rMin) system.addConstraint(iAtom, jAtom, rMin)
if rigidWater and shake == None: if rigidWater and shake is None:
for (iAtom, jAtom, k, rMin) in prmtop.getBondsWithH(): for (iAtom, jAtom, k, rMin) in prmtop.getBondsWithH():
if isWater[iAtom] and isWater[jAtom]: if isWater[iAtom] and isWater[jAtom]:
system.addConstraint(iAtom, jAtom, rMin) system.addConstraint(iAtom, jAtom, rMin)
......
...@@ -157,6 +157,9 @@ class AtomType(object): ...@@ -157,6 +157,9 @@ class AtomType(object):
return self.number == other return self.number == other
return other == (self.number, self.name) return other == (self.number, self.name)
def __ne__(self, other):
return not self.__eq__(self, other)
def set_lj_params(self, eps, rmin, eps14=None, rmin14=None): def set_lj_params(self, eps, rmin, eps14=None, rmin14=None):
""" Sets Lennard-Jones parameters on this atom type """ """ Sets Lennard-Jones parameters on this atom type """
if eps14 is None: if eps14 is None:
...@@ -220,6 +223,7 @@ class WildCard(AtomType): ...@@ -220,6 +223,7 @@ class WildCard(AtomType):
# Define comparison operators # Define comparison operators
def __eq__(self, other): return True def __eq__(self, other): return True
def __ne__(self, other): return False
def __lt__(self, other): return True def __lt__(self, other): return True
def __gt__(self, other): return False def __gt__(self, other): return False
def __le__(self, other): return True def __le__(self, other): return True
...@@ -985,6 +989,9 @@ class BondType(object): ...@@ -985,6 +989,9 @@ class BondType(object):
def __eq__(self, other): def __eq__(self, other):
return self.k == other.k and self.req == other.req return self.k == other.k and self.req == other.req
def __ne__(self, other):
return not self.__eq__(self, other)
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class AngleType(object): class AngleType(object):
...@@ -1005,6 +1012,9 @@ class AngleType(object): ...@@ -1005,6 +1012,9 @@ class AngleType(object):
def __eq__(self, other): def __eq__(self, other):
return self.k == other.k and self.theteq == other.theteq return self.k == other.k and self.theteq == other.theteq
def __ne__(self, other):
return not self.__eq__(self, other)
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class UreyBradleyType(BondType): class UreyBradleyType(BondType):
...@@ -1046,6 +1056,9 @@ class DihedralType(object): ...@@ -1046,6 +1056,9 @@ class DihedralType(object):
return (self.phi_k == other.phi_k and self.per == other.per and return (self.phi_k == other.phi_k and self.per == other.per and
self.phase == other.phase) self.phase == other.phase)
def __ne__(self, other):
return not self.__eq__(self, other)
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
class ImproperType(object): class ImproperType(object):
...@@ -1066,6 +1079,9 @@ class ImproperType(object): ...@@ -1066,6 +1079,9 @@ class ImproperType(object):
def __eq__(self, other): def __eq__(self, other):
return self.k == other.k and self.phieq == other.phieq return self.k == other.k and self.phieq == other.phieq
def __ne__(self, other):
return not self.__eq__(self, other)
def __repr__(self): def __repr__(self):
return '<ImproperType; k=%s; phieq=%s>' % (self.k, self.phieq) return '<ImproperType; k=%s; phieq=%s>' % (self.k, self.phieq)
...@@ -1101,6 +1117,9 @@ class CmapType(object): ...@@ -1101,6 +1117,9 @@ class CmapType(object):
return (self.resolution == other.resolution and return (self.resolution == other.resolution and
all([abs(i - j) < TINY for i, j in zip(self.grid, other.grid)])) all([abs(i - j) < TINY for i, j in zip(self.grid, other.grid)]))
def __ne__(self, other):
return not self.__eq__(self, other)
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Take the CmapGrid class from the Chamber prmtop topology objects # Take the CmapGrid class from the Chamber prmtop topology objects
...@@ -1198,6 +1217,9 @@ class _CmapGrid(object): ...@@ -1198,6 +1217,9 @@ class _CmapGrid(object):
except AttributeError: except AttributeError:
return TypeError('Bad type comparison with _CmapGrid') return TypeError('Bad type comparison with _CmapGrid')
def __ne__(self, other):
return not self.__eq__(self, other)
def switch_range(self): def switch_range(self):
""" """
Returns a grid object whose range is 0 to 360 degrees in both dimensions Returns a grid object whose range is 0 to 360 degrees in both dimensions
......
...@@ -226,7 +226,7 @@ class PdbStructure(object): ...@@ -226,7 +226,7 @@ class PdbStructure(object):
print("END", file=output_stream) print("END", file=output_stream)
def _add_model(self, model): def _add_model(self, model):
if self.default_model == None: if self.default_model is None:
self.default_model = model self.default_model = model
self.models.append(model) self.models.append(model)
self._current_model = model self._current_model = model
...@@ -292,7 +292,7 @@ class PdbStructure(object): ...@@ -292,7 +292,7 @@ class PdbStructure(object):
def _add_atom(self, atom): def _add_atom(self, atom):
""" """
""" """
if self._current_model == None: if self._current_model is None:
self._add_model(Model(0)) self._add_model(Model(0))
atom.model_number = self._current_model.number atom.model_number = self._current_model.number
# Atom might be alternate position for existing atom # Atom might be alternate position for existing atom
...@@ -560,20 +560,20 @@ class Residue(object): ...@@ -560,20 +560,20 @@ class Residue(object):
def set_name_with_spaces(self, name, alt_loc=None): def set_name_with_spaces(self, name, alt_loc=None):
# Gromacs ffamber PDB files can have 4-character residue names # Gromacs ffamber PDB files can have 4-character residue names
# assert len(name) == 3 # assert len(name) == 3
if alt_loc == None: if alt_loc is None:
alt_loc = self.primary_location_id alt_loc = self.primary_location_id
loc = self.locations[alt_loc] loc = self.locations[alt_loc]
loc.name_with_spaces = name loc.name_with_spaces = name
loc.name = name.strip() loc.name = name.strip()
def get_name_with_spaces(self, alt_loc=None): def get_name_with_spaces(self, alt_loc=None):
if alt_loc == None: if alt_loc is None:
alt_loc = self.primary_location_id alt_loc = self.primary_location_id
loc = self.locations[alt_loc] loc = self.locations[alt_loc]
return loc.name_with_spaces return loc.name_with_spaces
name_with_spaces = property(get_name_with_spaces, set_name_with_spaces, doc='four-character residue name including spaces') name_with_spaces = property(get_name_with_spaces, set_name_with_spaces, doc='four-character residue name including spaces')
def get_name(self, alt_loc=None): def get_name(self, alt_loc=None):
if alt_loc == None: if alt_loc is None:
alt_loc = self.primary_location_id alt_loc = self.primary_location_id
loc = self.locations[alt_loc] loc = self.locations[alt_loc]
return loc.name return loc.name
...@@ -616,7 +616,7 @@ class Residue(object): ...@@ -616,7 +616,7 @@ class Residue(object):
# Three possibilities: primary alt_loc, certain alt_loc, or all alt_locs # Three possibilities: primary alt_loc, certain alt_loc, or all alt_locs
def iter_atoms(self, alt_loc=None): def iter_atoms(self, alt_loc=None):
if alt_loc == None: if alt_loc is None:
locs = [self.primary_location_id] locs = [self.primary_location_id]
elif alt_loc == "": elif alt_loc == "":
locs = [self.primary_location_id] locs = [self.primary_location_id]
...@@ -629,7 +629,7 @@ class Residue(object): ...@@ -629,7 +629,7 @@ class Residue(object):
use_atom = False # start pessimistic use_atom = False # start pessimistic
for loc2 in atom.locations.keys(): for loc2 in atom.locations.keys():
# print "#%s#%s" % (loc2,locs) # print "#%s#%s" % (loc2,locs)
if locs == None: # means all locations if locs is None: # means all locations
use_atom = True use_atom = True
elif loc2 in locs: elif loc2 in locs:
use_atom = True use_atom = True
...@@ -805,7 +805,7 @@ class Atom(object): ...@@ -805,7 +805,7 @@ class Atom(object):
try: try:
# Try to find a sensible element symbol from columns 76-77 # Try to find a sensible element symbol from columns 76-77
self.element = element.get_by_symbol(self.element_symbol) self.element = element.get_by_symbol(self.element_symbol)
except KeyError: except KeyError:
self.element = None self.element = None
if pdbstructure is not None: if pdbstructure is not None:
pdbstructure._next_atom_number = self.serial_number+1 pdbstructure._next_atom_number = self.serial_number+1
...@@ -850,12 +850,12 @@ class Atom(object): ...@@ -850,12 +850,12 @@ class Atom(object):
# Hide existence of multiple alternate locations to avoid scaring casual users # Hide existence of multiple alternate locations to avoid scaring casual users
def get_location(self, location_id=None): def get_location(self, location_id=None):
id = location_id id = location_id
if (id == None): if id is None:
id = self.default_location_id id = self.default_location_id
return self.locations[id] return self.locations[id]
def set_location(self, new_location, location_id=None): def set_location(self, new_location, location_id=None):
id = location_id id = location_id
if (id == None): if id is None:
id = self.default_location_id id = self.default_location_id
self.locations[id] = new_location self.locations[id] = new_location
location = property(get_location, set_location, doc='default Atom.Location object') location = property(get_location, set_location, doc='default Atom.Location object')
...@@ -891,9 +891,9 @@ class Atom(object): ...@@ -891,9 +891,9 @@ class Atom(object):
""" """
Produce a PDB line for this atom using a particular serial number and alternate location Produce a PDB line for this atom using a particular serial number and alternate location
""" """
if serial_number == None: if serial_number is None:
serial_number = self.serial_number serial_number = self.serial_number
if alternate_location_indicator == None: if alternate_location_indicator is None:
alternate_location_indicator = self.alternate_location_indicator alternate_location_indicator = self.alternate_location_indicator
# produce PDB line in three parts: names, numbers, and end # produce PDB line in three parts: names, numbers, and end
# Accomodate 4-character residue names that use column 21 # Accomodate 4-character residue names that use column 21
...@@ -927,7 +927,7 @@ class Atom(object): ...@@ -927,7 +927,7 @@ class Atom(object):
alt_loc = None means write just the primary location alt_loc = None means write just the primary location
alt_loc = "AB" means write locations "A" and "B" alt_loc = "AB" means write locations "A" and "B"
""" """
if alt_loc == None: if alt_loc is None:
locs = [self.default_location_id] locs = [self.default_location_id]
elif alt_loc == "": elif alt_loc == "":
locs = [self.default_location_id] locs = [self.default_location_id]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment