{"action":"created","issue":{"url":"https://api.github.com/repos/ParmEd/ParmEd/issues/629","repository_url":"https://api.github.com/repos/ParmEd/ParmEd","labels_url":"https://api.github.com/repos/ParmEd/ParmEd/issues/629/labels{/name}","comments_url":"https://api.github.com/repos/ParmEd/ParmEd/issues/629/comments","events_url":"https://api.github.com/repos/ParmEd/ParmEd/issues/629/events","html_url":"https://github.com/ParmEd/ParmEd/issues/629","id":137986391,"number":629,"title":"OpenMMParameterSet - repeats of residues","user":{"login":"rafwiewiora","id":12088757,"avatar_url":"https://avatars.githubusercontent.com/u/12088757?v=3","gravatar_id":"","url":"https://api.github.com/users/rafwiewiora","html_url":"https://github.com/rafwiewiora","followers_url":"https://api.github.com/users/rafwiewiora/followers","following_url":"https://api.github.com/users/rafwiewiora/following{/other_user}","gists_url":"https://api.github.com/users/rafwiewiora/gists{/gist_id}","starred_url":"https://api.github.com/users/rafwiewiora/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rafwiewiora/subscriptions","organizations_url":"https://api.github.com/users/rafwiewiora/orgs","repos_url":"https://api.github.com/users/rafwiewiora/repos","events_url":"https://api.github.com/users/rafwiewiora/events{/privacy}","received_events_url":"https://api.github.com/users/rafwiewiora/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2016-03-02T20:39:28Z","updated_at":"2016-03-03T15:35:57Z","closed_at":null,"body":"Similar thing again - should it be in ParmEd or in my script?\r\n\r\natomic_ions.lib has some identical residue templates with different names - e.g. `K` and `K+` - now these both get written to the ffxml. This won't cause a bug in OpenMM - but it's kinda this 'undocumented behavior' of ForceField so we shouldn't do this - not even quite sure how to do this yet, one way would be too look for identical residue signatures in OpenMM - but that'd be post-writing the ffxml editing perhaps. "},"comment":{"url":"https://api.github.com/repos/ParmEd/ParmEd/issues/comments/191817177","html_url":"https://github.com/ParmEd/ParmEd/issues/629#issuecomment-191817177","issue_url":"https://api.github.com/repos/ParmEd/ParmEd/issues/629","id":191817177,"user":{"login":"rafwiewiora","id":12088757,"avatar_url":"https://avatars.githubusercontent.com/u/12088757?v=3","gravatar_id":"","url":"https://api.github.com/users/rafwiewiora","html_url":"https://github.com/rafwiewiora","followers_url":"https://api.github.com/users/rafwiewiora/followers","following_url":"https://api.github.com/users/rafwiewiora/following{/other_user}","gists_url":"https://api.github.com/users/rafwiewiora/gists{/gist_id}","starred_url":"https://api.github.com/users/rafwiewiora/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rafwiewiora/subscriptions","organizations_url":"https://api.github.com/users/rafwiewiora/orgs","repos_url":"https://api.github.com/users/rafwiewiora/repos","events_url":"https://api.github.com/users/rafwiewiora/events{/privacy}","received_events_url":"https://api.github.com/users/rafwiewiora/received_events","type":"User","site_admin":false},"created_at":"2016-03-03T15:35:57Z","updated_at":"2016-03-03T15:35:57Z","body":"Current situation:\r\n\r\n* no matching on names - matching is done based on 'residue signature' (which is just a string of elements in the residue and number of occurrences of the elements, e.g. `C5H10`) + identical bonding. \r\n\r\n* if you load in more than one identical residues: they get registered in the templates dictionary under the same template signature key:\r\n\r\n ``` python\r\ndef registerResidueTemplate(self, template):\r\n        \"\"\"Register a new residue template.\"\"\"\r\n        self._templates[template.name] = template\r\n        signature = _createResidueSignature([atom.element for atom in template.atoms])\r\n        if signature in self._templateSignatures:\r\n            self._templateSignatures[signature].append(template)\r\n        else:\r\n            self._templateSignatures[signature] = [template]\r\n```\r\n\r\n That's where the behavior becomes 'undefined' because you've just introduced an order in that list that depends on the order of loading in these templates. And a bunch of loops in the ForceField `break` when they have found something - all of this `undefined` behavior really comes from the lack of mechanism to check for duplicates, which I guess partially comes from a decision to increase efficiency by not completing loops. \r\n\r\n So going further, when you come to match your templates with topology:\r\n ``` python\r\ndef _getResidueTemplateMatches(self, res, bondedToAtom):\r\n        template = None\r\n        matches = None\r\n        signature = _createResidueSignature([atom.element for atom in res.atoms()])\r\n        if signature in self._templateSignatures:\r\n            for t in self._templateSignatures[signature]:\r\n                matches = _matchResidue(res, t, bondedToAtom)\r\n                if matches is not None:\r\n                    template = t\r\n                    break\r\n        return [template, matches]\r\n```\r\n\r\nYou can see you will take the first template that matches on the signature and on bonding (through the `_matchResidue` algorithm - [line 987](https://github.com/pandegroup/openmm/blob/master/wrappers/python/simtk/openmm/app/forcefield.py#L987)) - so the behavior is somewhat 'defined' - it will always take the first-to-have-been-loaded template that matches. \r\n\r\nClearly we need to tighten this up for the overriding. I think we're going to need to let go of some efficiency and do these loops over everything - so if more than one matching template found - exception. I wouldn't want to complicate this further by allowing more than one matching template if the templates are identical - OpenMM obviously doesn't have the different Pdb format issue because it doesn't match by name. \r\n\r\nSo what is the best way to get rid of these duplicates?\r\n\r\n"}}