{"action":"created","comment":{"url":"https://api.github.com/repos/pandegroup/openmm/pulls/comments/55613222","id":55613222,"diff_hunk":"@@ -448,6 +448,179 @@ def test_getMatchingTemplates(self):\n         self.assertEqual(templates[1].name, 'ALA')\n         self.assertEqual(templates[2].name, 'CALA')\n \n+    def test_Wildcard(self):\n+        \"\"\"Test that PeriodicTorsionForces using wildcard ('') for atom types / classes in the ffxml are correctly registered\"\"\"\n+\n+        # Use wildcards in types\n+        xml = \"\"\"\n+<ForceField>\n+ <AtomTypes>\n+  <Type name=\"C\" class=\"C\" element=\"C\" mass=\"12.010000\"/>\n+  <Type name=\"O\" class=\"O\" element=\"O\" mass=\"16.000000\"/>\n+ </AtomTypes>\n+ <PeriodicTorsionForce>\n+  <Proper type1=\"\" type2=\"C\" type3=\"C\" type4=\"\" periodicity1=\"2\" phase1=\"3.141593\" k1=\"15.167000\"/>\n+  <Improper type1=\"C\" type2=\"\" type3=\"\" type4=\"O\" periodicity1=\"2\" phase1=\"3.141593\" k1=\"43.932000\"/>\n+ </PeriodicTorsionForce>\n+</ForceField>\"\"\"\n+\n+        ff = ForceField(StringIO(xml))\n+\n+        self.assertEqual(len(ff._forces[0].proper), 1)\n+        self.assertEqual(len(ff._forces[0].improper), 1)\n+\n+       # Use wildcards in classes\n+        xml = \"\"\"\n+<ForceField>\n+ <AtomTypes>\n+  <Type name=\"C\" class=\"C\" element=\"C\" mass=\"12.010000\"/>\n+  <Type name=\"O\" class=\"O\" element=\"O\" mass=\"16.000000\"/>\n+ </AtomTypes>\n+ <PeriodicTorsionForce>\n+  <Proper class1=\"\" class2=\"C\" class3=\"C\" class4=\"\" periodicity1=\"2\" phase1=\"3.141593\" k1=\"15.167000\"/>\n+  <Improper class1=\"C\" class2=\"\" class3=\"\" class4=\"O\" periodicity1=\"2\" phase1=\"3.141593\" k1=\"43.932000\"/>\n+ </PeriodicTorsionForce>\n+</ForceField>\"\"\"\n+\n+        ff = ForceField(StringIO(xml))\n+\n+        self.assertEqual(len(ff._forces[0].proper), 1)\n+        self.assertEqual(len(ff._forces[0].improper), 1)\n+\n+    def test_ScalingFactorCombining(self):\n+        \"\"\" Tests that FFs can be combined if their scaling factors are very close \"\"\"\n+        forcefield = ForceField('amber99sb.xml', os.path.join('systems', 'test_amber_ff.xml'))\n+        # This would raise an exception if it didn't work\n+\n+    def test_MultipleFilesandForceTags(self):\n+        \"\"\"Test that the order of listing of multiple ffxmls does not matter.\n+           Tests that one generator per force type is created and that the ffxml\n+           defining atom types does not have to be listed first\"\"\"\n+\n+        ffxml = \"\"\"<ForceField>\n+ <Residues>\n+  <Residue name=\"ACE-Test\">\n+   <Atom name=\"HH31\" type=\"710\"/>\n+   <Atom name=\"CH3\" type=\"711\"/>\n+   <Atom name=\"HH32\" type=\"710\"/>\n+   <Atom name=\"HH33\" type=\"710\"/>\n+   <Atom name=\"C\" type=\"712\"/>\n+   <Atom name=\"O\" type=\"713\"/>\n+   <Bond from=\"0\" to=\"1\"/>\n+   <Bond from=\"1\" to=\"2\"/>\n+   <Bond from=\"1\" to=\"3\"/>\n+   <Bond from=\"1\" to=\"4\"/>\n+   <Bond from=\"4\" to=\"5\"/>\n+   <ExternalBond from=\"4\"/>\n+  </Residue>\n+ </Residues>\n+ <PeriodicTorsionForce>\n+  <Proper class1=\"C\" class2=\"C\" class3=\"C\" class4=\"C\" periodicity1=\"2\" phase1=\"3.14159265359\" k1=\"10.46\"/>\n+  <Improper class1=\"C\" class2=\"C\" class3=\"C\" class4=\"C\" periodicity1=\"2\" phase1=\"3.14159265359\" k1=\"43.932\"/>\n+ </PeriodicTorsionForce>\n+</ForceField>\"\"\"\n+\n+        ff1 = ForceField(StringIO(ffxml), 'amber99sbildn.xml')\n+        ff2 = ForceField('amber99sbildn.xml', StringIO(ffxml))\n+\n+        self.assertEqual(len(ff1._forces), 4)\n+        self.assertEqual(len(ff2._forces), 4)\n+\n+        pertorsion1 = ff1._forces[0]\n+        pertorsion2 = ff2._forces[2]\n+\n+        self.assertEqual(len(pertorsion1.proper), 110)\n+        self.assertEqual(len(pertorsion1.improper), 42)\n+        self.assertEqual(len(pertorsion2.proper), 110)\n+        self.assertEqual(len(pertorsion2.improper), 42)\n+\n+    def test_ResidueTemplateUserChoice(self):\n+        \"\"\"Test createSystem does not allow multiple matching templates, unless\n+           user has specified which template to use via residueTemplates arg\"\"\"\n+        ffxml = \"\"\"<ForceField>\n+ <AtomTypes>\n+  <Type name=\"Fe2+\" class=\"Fe2+\" element=\"Fe\" mass=\"55.85\"/>\n+  <Type name=\"Fe3+\" class=\"Fe3+\" element=\"Fe\" mass=\"55.85\"/>\n+ </AtomTypes>\n+ <Residues>\n+  <Residue name=\"FE2\">\n+   <Atom name=\"FE2\" type=\"Fe2+\" charge=\"2.0\"/>\n+  </Residue>\n+  <Residue name=\"FE\">\n+   <Atom name=\"FE\" type=\"Fe3+\" charge=\"3.0\"/>\n+  </Residue>\n+ </Residues>\n+ <NonbondedForce coulomb14scale=\"0.833333333333\" lj14scale=\"0.5\">\n+  <UseAttributeFromResidue name=\"charge\"/>\n+  <Atom type=\"Fe2+\" sigma=\"0.227535532613\" epsilon=\"0.0150312292\"/>\n+  <Atom type=\"Fe3+\" sigma=\"0.192790482606\" epsilon=\"0.00046095128\"/>\n+ </NonbondedForce>\n+</ForceField>\"\"\"\n+\n+        pdb_string = \"ATOM      1 FE    FE A   1      20.956  27.448 -29.067  1.00  0.00          Fe\"\n+        ff = ForceField(StringIO(ffxml))\n+        pdb = PDBFile(StringIO(pdb_string))\n+\n+        self.assertRaises(Exception, lambda: ff.createSystem(pdb.topology))\n+        ff.createSystem(pdb.topology, residueTemplates={list(pdb.topology.residues())[0] : 'FE2'})\n+        ff.createSystem(pdb.topology, residueTemplates={list(pdb.topology.residues())[0] : 'FE'})","path":"wrappers/python/tests/TestForceField.py","position":119,"original_position":119,"commit_id":"4aa8df6d35c4d31fc5d15777c6a74b9bd4d69ae1","original_commit_id":"4aa8df6d35c4d31fc5d15777c6a74b9bd4d69ae1","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},"body":"Sure, good point!","created_at":"2016-03-10T00:05:16Z","updated_at":"2016-03-10T00:05:16Z","html_url":"https://github.com/pandegroup/openmm/pull/1373#discussion_r55613222","pull_request_url":"https://api.github.com/repos/pandegroup/openmm/pulls/1373","_links":{"self":{"href":"https://api.github.com/repos/pandegroup/openmm/pulls/comments/55613222"},"html":{"href":"https://github.com/pandegroup/openmm/pull/1373#discussion_r55613222"},"pull_request":{"href":"https://api.github.com/repos/pandegroup/openmm/pulls/1373"}}},"pull_request":{"url":"https://api.github.com/repos/pandegroup/openmm/pulls/1373","id":57567468,"html_url":"https://github.com/pandegroup/openmm/pull/1373","diff_url":"https://github.com/pandegroup/openmm/pull/1373.diff","patch_url":"https://github.com/pandegroup/openmm/pull/1373.patch","issue_url":"https://api.github.com/repos/pandegroup/openmm/issues/1373","number":1373,"state":"open","locked":false,"title":"Residue template overloading / User can specify template if multiple match / Refactor XML loading / No multiple gens","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},"body":"","created_at":"2016-01-28T21:19:04Z","updated_at":"2016-03-10T00:05:16Z","closed_at":null,"merged_at":null,"merge_commit_sha":"a75dd01a4ee9011450ba141e825da54e8a8b0409","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/pandegroup/openmm/pulls/1373/commits","review_comments_url":"https://api.github.com/repos/pandegroup/openmm/pulls/1373/comments","review_comment_url":"https://api.github.com/repos/pandegroup/openmm/pulls/comments{/number}","comments_url":"https://api.github.com/repos/pandegroup/openmm/issues/1373/comments","statuses_url":"https://api.github.com/repos/pandegroup/openmm/statuses/4aa8df6d35c4d31fc5d15777c6a74b9bd4d69ae1","head":{"label":"rafwiewiora:forcefield_xml","ref":"forcefield_xml","sha":"4aa8df6d35c4d31fc5d15777c6a74b9bd4d69ae1","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},"repo":{"id":42333124,"name":"openmm","full_name":"rafwiewiora/openmm","owner":{"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},"private":false,"html_url":"https://github.com/rafwiewiora/openmm","description":"OpenMM is a toolkit for molecular simulation using high performance GPU code. ","fork":true,"url":"https://api.github.com/repos/rafwiewiora/openmm","forks_url":"https://api.github.com/repos/rafwiewiora/openmm/forks","keys_url":"https://api.github.com/repos/rafwiewiora/openmm/keys{/key_id}","collaborators_url":"https://api.github.com/repos/rafwiewiora/openmm/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/rafwiewiora/openmm/teams","hooks_url":"https://api.github.com/repos/rafwiewiora/openmm/hooks","issue_events_url":"https://api.github.com/repos/rafwiewiora/openmm/issues/events{/number}","events_url":"https://api.github.com/repos/rafwiewiora/openmm/events","assignees_url":"https://api.github.com/repos/rafwiewiora/openmm/assignees{/user}","branches_url":"https://api.github.com/repos/rafwiewiora/openmm/branches{/branch}","tags_url":"https://api.github.com/repos/rafwiewiora/openmm/tags","blobs_url":"https://api.github.com/repos/rafwiewiora/openmm/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/rafwiewiora/openmm/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/rafwiewiora/openmm/git/refs{/sha}","trees_url":"https://api.github.com/repos/rafwiewiora/openmm/git/trees{/sha}","statuses_url":"https://api.github.com/repos/rafwiewiora/openmm/statuses/{sha}","languages_url":"https://api.github.com/repos/rafwiewiora/openmm/languages","stargazers_url":"https://api.github.com/repos/rafwiewiora/openmm/stargazers","contributors_url":"https://api.github.com/repos/rafwiewiora/openmm/contributors","subscribers_url":"https://api.github.com/repos/rafwiewiora/openmm/subscribers","subscription_url":"https://api.github.com/repos/rafwiewiora/openmm/subscription","commits_url":"https://api.github.com/repos/rafwiewiora/openmm/commits{/sha}","git_commits_url":"https://api.github.com/repos/rafwiewiora/openmm/git/commits{/sha}","comments_url":"https://api.github.com/repos/rafwiewiora/openmm/comments{/number}","issue_comment_url":"https://api.github.com/repos/rafwiewiora/openmm/issues/comments{/number}","contents_url":"https://api.github.com/repos/rafwiewiora/openmm/contents/{+path}","compare_url":"https://api.github.com/repos/rafwiewiora/openmm/compare/{base}...{head}","merges_url":"https://api.github.com/repos/rafwiewiora/openmm/merges","archive_url":"https://api.github.com/repos/rafwiewiora/openmm/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/rafwiewiora/openmm/downloads","issues_url":"https://api.github.com/repos/rafwiewiora/openmm/issues{/number}","pulls_url":"https://api.github.com/repos/rafwiewiora/openmm/pulls{/number}","milestones_url":"https://api.github.com/repos/rafwiewiora/openmm/milestones{/number}","notifications_url":"https://api.github.com/repos/rafwiewiora/openmm/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/rafwiewiora/openmm/labels{/name}","releases_url":"https://api.github.com/repos/rafwiewiora/openmm/releases{/id}","deployments_url":"https://api.github.com/repos/rafwiewiora/openmm/deployments","created_at":"2015-09-11T21:28:42Z","updated_at":"2016-01-18T20:44:02Z","pushed_at":"2016-03-09T23:57:54Z","git_url":"git://github.com/rafwiewiora/openmm.git","ssh_url":"git@github.com:rafwiewiora/openmm.git","clone_url":"https://github.com/rafwiewiora/openmm.git","svn_url":"https://github.com/rafwiewiora/openmm","homepage":null,"size":98255,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"pandegroup:master","ref":"master","sha":"9b5b52f2bf2e851efdd0733fed3e83a24d9f16af","user":{"login":"pandegroup","id":2250873,"avatar_url":"https://avatars.githubusercontent.com/u/2250873?v=3","gravatar_id":"","url":"https://api.github.com/users/pandegroup","html_url":"https://github.com/pandegroup","followers_url":"https://api.github.com/users/pandegroup/followers","following_url":"https://api.github.com/users/pandegroup/following{/other_user}","gists_url":"https://api.github.com/users/pandegroup/gists{/gist_id}","starred_url":"https://api.github.com/users/pandegroup/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pandegroup/subscriptions","organizations_url":"https://api.github.com/users/pandegroup/orgs","repos_url":"https://api.github.com/users/pandegroup/repos","events_url":"https://api.github.com/users/pandegroup/events{/privacy}","received_events_url":"https://api.github.com/users/pandegroup/received_events","type":"Organization","site_admin":false},"repo":{"id":10178188,"name":"openmm","full_name":"pandegroup/openmm","owner":{"login":"pandegroup","id":2250873,"avatar_url":"https://avatars.githubusercontent.com/u/2250873?v=3","gravatar_id":"","url":"https://api.github.com/users/pandegroup","html_url":"https://github.com/pandegroup","followers_url":"https://api.github.com/users/pandegroup/followers","following_url":"https://api.github.com/users/pandegroup/following{/other_user}","gists_url":"https://api.github.com/users/pandegroup/gists{/gist_id}","starred_url":"https://api.github.com/users/pandegroup/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pandegroup/subscriptions","organizations_url":"https://api.github.com/users/pandegroup/orgs","repos_url":"https://api.github.com/users/pandegroup/repos","events_url":"https://api.github.com/users/pandegroup/events{/privacy}","received_events_url":"https://api.github.com/users/pandegroup/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/pandegroup/openmm","description":"OpenMM is a toolkit for molecular simulation using high performance GPU code. ","fork":false,"url":"https://api.github.com/repos/pandegroup/openmm","forks_url":"https://api.github.com/repos/pandegroup/openmm/forks","keys_url":"https://api.github.com/repos/pandegroup/openmm/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pandegroup/openmm/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pandegroup/openmm/teams","hooks_url":"https://api.github.com/repos/pandegroup/openmm/hooks","issue_events_url":"https://api.github.com/repos/pandegroup/openmm/issues/events{/number}","events_url":"https://api.github.com/repos/pandegroup/openmm/events","assignees_url":"https://api.github.com/repos/pandegroup/openmm/assignees{/user}","branches_url":"https://api.github.com/repos/pandegroup/openmm/branches{/branch}","tags_url":"https://api.github.com/repos/pandegroup/openmm/tags","blobs_url":"https://api.github.com/repos/pandegroup/openmm/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pandegroup/openmm/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pandegroup/openmm/git/refs{/sha}","trees_url":"https://api.github.com/repos/pandegroup/openmm/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pandegroup/openmm/statuses/{sha}","languages_url":"https://api.github.com/repos/pandegroup/openmm/languages","stargazers_url":"https://api.github.com/repos/pandegroup/openmm/stargazers","contributors_url":"https://api.github.com/repos/pandegroup/openmm/contributors","subscribers_url":"https://api.github.com/repos/pandegroup/openmm/subscribers","subscription_url":"https://api.github.com/repos/pandegroup/openmm/subscription","commits_url":"https://api.github.com/repos/pandegroup/openmm/commits{/sha}","git_commits_url":"https://api.github.com/repos/pandegroup/openmm/git/commits{/sha}","comments_url":"https://api.github.com/repos/pandegroup/openmm/comments{/number}","issue_comment_url":"https://api.github.com/repos/pandegroup/openmm/issues/comments{/number}","contents_url":"https://api.github.com/repos/pandegroup/openmm/contents/{+path}","compare_url":"https://api.github.com/repos/pandegroup/openmm/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pandegroup/openmm/merges","archive_url":"https://api.github.com/repos/pandegroup/openmm/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pandegroup/openmm/downloads","issues_url":"https://api.github.com/repos/pandegroup/openmm/issues{/number}","pulls_url":"https://api.github.com/repos/pandegroup/openmm/pulls{/number}","milestones_url":"https://api.github.com/repos/pandegroup/openmm/milestones{/number}","notifications_url":"https://api.github.com/repos/pandegroup/openmm/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pandegroup/openmm/labels{/name}","releases_url":"https://api.github.com/repos/pandegroup/openmm/releases{/id}","deployments_url":"https://api.github.com/repos/pandegroup/openmm/deployments","created_at":"2013-05-20T17:42:52Z","updated_at":"2016-02-25T23:04:02Z","pushed_at":"2016-03-09T23:57:54Z","git_url":"git://github.com/pandegroup/openmm.git","ssh_url":"git@github.com:pandegroup/openmm.git","clone_url":"https://github.com/pandegroup/openmm.git","svn_url":"https://github.com/pandegroup/openmm","homepage":null,"size":104061,"stargazers_count":134,"watchers_count":134,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":79,"mirror_url":null,"open_issues_count":143,"forks":79,"open_issues":143,"watchers":134,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/pandegroup/openmm/pulls/1373"},"html":{"href":"https://github.com/pandegroup/openmm/pull/1373"},"issue":{"href":"https://api.github.com/repos/pandegroup/openmm/issues/1373"},"comments":{"href":"https://api.github.com/repos/pandegroup/openmm/issues/1373/comments"},"review_comments":{"href":"https://api.github.com/repos/pandegroup/openmm/pulls/1373/comments"},"review_comment":{"href":"https://api.github.com/repos/pandegroup/openmm/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/pandegroup/openmm/pulls/1373/commits"},"statuses":{"href":"https://api.github.com/repos/pandegroup/openmm/statuses/4aa8df6d35c4d31fc5d15777c6a74b9bd4d69ae1"}}}}