Skip to content
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

CHARMM: Handle patches #22

Closed
jchodera opened this issue Apr 14, 2017 · 91 comments
Closed

CHARMM: Handle patches #22

jchodera opened this issue Apr 14, 2017 · 91 comments
Assignees

Comments

@jchodera
Copy link
Member

jchodera commented Apr 14, 2017

Since the CHARMM forcefield only specified patch/residue compatibility with (barely) human-readable comments (see #1 (comment)), we plan to create a YAML file to direct which ffxml compatibility tags are to be inserted.

The initial version will cover

  • Common N- and C-terminal patches (NTER, CTER, ACE/NME)
  • Disulfides
  • Common modifications for kinases (phosphoserine, tyrosine, threonine in different protonation states)

The syntax will look something like

charmm-patches.yaml:
---
residues:
   ALA:
      - NTER
      - CTER

patches:
   DISU:
      - 1:CYS
      - 2:CYS

In future iterations, we will expand this compatibility list.

@jchodera jchodera changed the title CHARMM: Add capability to convert CHARMM patches to new ffxml format to ParmEd CHARMM: Add YAML syntax for manually specifying patch/residue compatibility Apr 19, 2017
@ChayaSt
Copy link
Contributor

ChayaSt commented Apr 20, 2017

@jchodera, I'm running into a problem when writing out the patches in the format that @peastman had documented here

This is what the patch looks like in CHARMM.

  • It doesn't differentiate between atoms that it adds to atoms that it just changes the type.

  • In addition, it doesn't specify the bonds to remove (or external bonds but here I can just assume that all NTER and CTER patches will remove the N and C external bonds). While it does tell you which atom to delete, you need to know the residue template it will be added to to know know which bond it will remove. But when it is loaded into Parmed, it doesn't know which residue it will be patched to.

  • We also need to add the partial charges but that can easily be added to AddAtom charge=' '

For the first two problems, we can probably devise a way to use the yaml file to find the template of the residues the patch will be patched to to figure out which atoms are changed rather than added and which bonds to remove, but that would mean using the yaml file in Parmed. Maybe @swails can offer some insight?

@jchodera
Copy link
Member Author

jchodera commented Apr 20, 2017

@peastman : We hadn't realized that this was going to be so problematic when the <Patch> spec was being defined.

The most straightforward solution here would be to modify the OpenMM <Patch> spec to support a change in behavior when the patch is applied:

  • patch-specified atoms would be added if they don't exist in the original residue template, or their types are modified if they already exist; partial charges are handled the same way
  • internal and external bonds in the original template to atoms deleted by the patch would automatically be deleted

We discussed the alternatives---engineering a separate pipeline or trying to massively overhaul ParmEd---and think that it will set us back a few weeks if we need to go that route. We need to fix the <Patch> spec anyway because the ability to specify partial charge changes was accidentally omitted in the first version of the spec...

@peastman
Copy link
Member

Since we're only including a handful of patches (NTER, CTER, DISU, and is that it?), what about just writing them by hand? That should be trivial to do. If we want to support a large set of them in the future, we can worry about getting ParmEd to generate them at that point.

@jchodera
Copy link
Member Author

@peastman: There's a few issues with manual generation of patches:

  • The current <Patch> spec doesn't include the ability to modify charges
  • There isn't an easy way forward to automatically generating these patches on a larger set without the changes proposed
  • We are checking on this, but I believe that, since the atoms deleted from the residue the patch is applied to *could depend on the target residue, there is actually no way to make patches behave correctly without making an OpenMM patch for every combination of CHARMM patch with every CHARMM residue, which was what we were hoping to avoid

@ChayaSt and I feel the best thing to do is to make these changes to the <Patch> spec now rather than be trapped by a problematic spec later. I don't think there's anything using the <Patch> function currently, and I'd be happy to make the changes in a PR.

@peastman
Copy link
Member

The current spec doesn't include the ability to modify charges

It actually does. I may have forgotten to mention that in the documentation. Sorry if I did! If you specify charge= on your <AddAtom> and <ChangeAtom> tags, that should work correctly.

internal and external bonds in the original template to atoms deleted by the patch would automatically be deleted

It already does that too.

patch-specified atoms would be added if they don't exist in the original residue template, or their types are modified if they already exist

I do see how this would simplify the process of automatically converting the CHARMM files, and let's discuss ways of handling it. But since we're only talking about three patches that can trivially be converted by hand, this isn't actually blocking anything, is it?

@ChayaSt
Copy link
Contributor

ChayaSt commented Apr 20, 2017

I do see how this would simplify the process of automatically converting the CHARMM files, and let's discuss ways of handling it. But since we're only talking about three patches that can trivially be converted by hand, this isn't actually blocking anything, is it?

It's actually more than 3 since I'm including the common termini (total of 8), specific termini for GLY and PRO (another 4), protonations and deprotonations (6), disulfide (1), and all phosphorylation (6). This is a total of 25. A bit much to do by hand...

@peastman
Copy link
Member

Ok, let's try to do something automated then.

Could the YAML file list the atoms that are being changed rather than added? I'm just trying to figure out a way to avoid removing error checking from OpenMM. Adding a new atom and changing an existing atom are fairly different operations, and making the user specify in the force field XML which one they're doing could catch a lot of user errors. I want to keep that protection if possible.

@jchodera
Copy link
Member Author

We don't actually have any way to know exactly which atoms and bonds should be deleted since the charmm patches do not provide this information, so there is no fundamentally superior way to check for errors in this case. What if the error checking was skipped only for patches that have a "behavior=charmm" attribute?

@ChayaSt
Copy link
Contributor

ChayaSt commented Apr 20, 2017

Could the YAML file list the atoms that are being changed rather than added?

That can be tough because the CHARMM template doesn't differentiate. All it gives you is a list of atoms from which some are changed and some are added.

@peastman
Copy link
Member

I know, you'd have to add that information yourself. For example, the NTER patch just lists six atoms: N, HT1, HT2, HT3, CA, and HA. It doesn't say which are added and which are changed. But you know that HT1, HT2, and HT3 are being added while N, CA, and HA are being changed. That's why I suggested putting it in the yaml file.

To put it differently: CHARMM really ought to provide that information, and it's a flaw in their design that it doesn't! OpenMM's design is better. I'd rather keep it that way, even if it means having to fill in the missing information by hand at conversion time, rather than force OpenMM to adopt the same design flaws that CHARMM has.

@jchodera
Copy link
Member Author

Except we don't know that for certain. We do not have that information available, and the only way to know what atoms are deleted is to discern this from a particular combination of patch with residue that should be allowed. We also believe there are cases where the atoms that are deleted will be different for different target residues.

I understand you have issues with how CHARMM represents this information, but I also understand that you would like to make the CHARMM forcefield available in OpenMM. In the end, there is always a compromise that must be made, and we're suggesting a logical compromise that mimics the behavior of CHARMM is the right compromise here.

@jchodera
Copy link
Member Author

To put it differently: CHARMM really ought to provide that information, and it's a flaw in their design that it doesn't! OpenMM's design is better. I'd rather keep it that way, even if it means having to fill in the missing information by hand at conversion time, rather than force OpenMM to adopt the same design flaws that CHARMM has.

Also, CHARMM clearly permits any of these combinations, meaning they are utterly valid in the CHARMM world. Who are we to say what is or isn't appropriate in the CHARMM world?

@peastman
Copy link
Member

Except we don't know that for certain.

We do know that. Remember that the XML file has to explicitly specify what patches can be applied to what templates. They don't get combined in arbitrary ways, only in the ways we specifically enumerate.

A "patch" in OpenMM is something very different from a "patch" in CHARMM, even though we use the same name for both of them. In retrospect maybe we should have chosen a different name to avoid that confusion. A CHARMM patch is a set of rules for modifying residues. The user tells the program, "Apply this patch to this residue," and it makes the modifications. An OpenMM patch doesn't modify anything. The system already has whatever atoms and bonds it's going to have, and we don't change that. The patch is a rule for generating new templates for parameter assignment. The user doesn't tell it what patches to apply. Instead, it automatically figures out what patched template is needed to match a residue.

So even though the OpenMM "patches" are (mostly) generated from the information contained in CHARMM "patches", they're not the same thing. Sometimes we'll need to supply extra information. Sometimes there may not be a 1:1 correspondence between CHARMM patches and OpenMM patches. That's not a problem. But if we try to think of them as actually the same thing, that will lead us into confusion.

@ChayaSt
Copy link
Contributor

ChayaSt commented Apr 21, 2017

We also believe there are cases where the atoms that are deleted will be different for different target residues.

An example of this it PRO. The N there is type N rather than NH1. While it has its own NTER and ACP patch, it doesn't have its own NNEU where the N is changed to an NH2 from either an NH1 for the other residues and from N for PRO.

@peastman
Copy link
Member

That means we'll need to create one version of the patch for PRO, and a different one for all the other amino acids. Not a problem. The force field explicitly specifies what patches can be applied to what templates.

@jchodera
Copy link
Member Author

Except we don't know that for certain.
We do know that. Remember that the XML file has to explicitly specify what patches can be applied to what templates. They don't get combined in arbitrary ways, only in the ways we specifically enumerate.

No, we don't know that for CHARMM because the information is not provided.

What you suggest amounts to preenumerating all possible combinations of patches and residues, which is what the Patch tag was meant to avoid. I don't think this is a solution that will gracefully scale to the whole charmm forcefield. Someone may be able to hack it together manually with a few days of effort (we won't be doing that here), but we won't easily be able to extend this later.

The Patch scheme was implemented to make CHARMM work. There is an easy way to fix the implementation to make CHARMM work with minimal effort without compromising the OpenMM error checking for anything that isn't already permissible by CHARMM. I'm not sure why there is resistance to this.

We will have to circle back and schedule a discussion by Skype for Monday or Tuesday of next week to sort out remaining issues. Today is unfortunately packed.

@peastman
Copy link
Member

What you suggest amounts to preenumerating all possible combinations of patches and residues, which is what the Patch tag was meant to avoid.

No, that is exactly what the patch tag requires. Please look at the spec (which you agreed to when it was implemented!) to see how it works. You're making claims that just aren't correct. You either have to include an <AllowPatch> inside the <Residue> tag, or else include an <ApplyToResidue> inside the <Patch> tag. Either way, the XML file explicitly enumerates every allowed combination of patch and template. If a combination isn't listed, it will never be used.

@jchodera
Copy link
Member Author

@peastman : I think there's still a bit of confusion over what we're proposing to change. We can still provide and require this---it's necessary to prevent combinatorial explosion for OpenMM---but we are suggesting that the determination of which atoms are changed vs which atoms are added should be made automatically at the time of Patch application. If we don't do this, we will need to pre-enumerate all possible combinations and split out patches into multiple patches automatically before creating the Patch records in a manner that I don't think will scale.

You were worried that we are eliminating error checking by not explicitly specifying which atoms are added vs changed in the patch---information the CHARMM PRES doesn't provide---but @ChayaSt discovered CHARMM adds a different kind of sanity check: The net charge change. The PRES record provides the total charge change expected after application of the patch in the first line (such as -1.00 for the PRES CTER below). We could use this as a substitute sanity check.

PRES CTER        -1.00 ! standard C-terminus
GROUP                  ! use in generate statement
ATOM C    CC      0.34 !   OT2(-)
ATOM OT1  OC     -0.67 !  /
ATOM OT2  OC     -0.67 ! -C
DELETE ATOM O          !  \\
BOND C OT2             !   OT1
DOUBLE  C OT1
IMPR C CA OT2 OT1
ACCEPTOR OT1 C   
ACCEPTOR OT2 C   
IC N    CA   C    OT2   0.0000  0.0000  180.0000  0.0000  0.0000
IC OT2  CA   *C   OT1   0.0000  0.0000  180.0000  0.0000  0.0000

@peastman
Copy link
Member

Yep, that's exactly what I'm proposing.

There's missing information in the CHARMM file. We need to fill that in. Do we do that at force field conversion time, or at system construction time?

In the first case, it happens in code that's run exactly once, when the force field is converted. We can check over the results carefully, validate them thoroughly, make sure everything is correct.

In the second case, it's code that runs every single time a user calls createSystem(). If there's a bug in that code, it might only show up in special circumstances. It will affect not just this force field we're creating now, but every force field with patches that will ever be created in the future by any user. It removes safety checks that would otherwise have caught mistakes those users make.

It seems pretty obvious to me which one is the better approach.

If we don't do this, we will need to pre-enumerate all possible combinations

You have to do that regardless. The XML file explicitly enumerates all allowed combinations. That's remains true either way.

@jchodera
Copy link
Member Author

You have to do that regardless. The XML file explicitly enumerates all allowed combinations. That's remains true either way.

You're asking us to explicitly enumerate not only all allowed combinations, but also break these up into classes that require different sets of atom additions and atom alterations. Right now, this can only be done by manually inspecting each (PRES, RESI) pair for something like 25 patches.

Let's rule out the manual approach. Even if it was something reasonable this time, it won't scale in the future.

Let me look into what ParmEd might do to facilitate the automated enumeration of combinations and their segregation into sub-patch types depending on which sets of atoms are added vs altered.

If you're concerned about safety checks, I presume we'll also implement the total charge change safety check into OpenMM as well?

@jchodera
Copy link
Member Author

jchodera commented Apr 24, 2017

@ChayaSt : Does ParmEd handle the storage and writing of patches yet, or do we need to add that as well? I tried checking the list params_omm.residues from the conversion script, but it looks like none of the residues loaded are patches.

@jchodera jchodera changed the title CHARMM: Add YAML syntax for manually specifying patch/residue compatibility CHARMM: Handle patches Apr 24, 2017
@swails
Copy link

swails commented Apr 24, 2017

ParmEd does "handle" patches (see here), but currently it just keeps a list of atoms that need deleting in addition to the information stored in a residue template.

That was the extent of how I was using patches at the time, so if it needs to be extended (as I suspect it does), then it can be.

@jchodera
Copy link
Member Author

Thanks, @swails!

Any idea where the .delete list is actually populated with atoms the patch specifies should be deleted? I don't see that handled anywhere in the CHARMM parameter file reader.

We're talking with @peastman today to figure out exactly what needs to be done with patch writing for OpenMM, then will open a PR with the proposed changes!

@jchodera
Copy link
Member Author

@swails: One more question: In CHARMM, patches (PRES) contain total residue charge that turns out to be important as a sanity check. The RESI residues contain this as well, but the total charge should just be a sum of the partial atomic charges (unlike in PRES). If we add a total_charge attribute, would you prefer we add that to ResidueTemplate or PatchTemplate?

@jchodera
Copy link
Member Author

@peastman : I think we can, within ParmEd, enumerate all "safe" combinations of patches using the total charge as a sanity check to exclude impermissible combinations. So listing residue compatibilities shouldn't be problematic.

I think we have to decide whether to add to ForceField an option to allow the CHARMM behavior of either adding or changing atoms to a residue when a patch is applied. If we don't, it significantly increases the complexity of what we have to do in ParmEd unless we actually create one new patch for every (residue,patch) combination, which is what we were hoping to avoid in the first place. We can discuss on today's call!

@jchodera
Copy link
Member Author

jchodera commented Sep 9, 2017

If only specifying one of them is the right thing to do, which one is it?

@jchodera
Copy link
Member Author

jchodera commented Sep 9, 2017

I can't come up with compelling arguments for one way vs the other, which is why I'm thinking that specifying only one of them isn't the right thing to do.

@peastman
Copy link
Member

peastman commented Sep 9, 2017

It doesn't matter. I just included both options for flexibility when combining multiple files. If you create a file that adds parameters for a new amino acid, you can use <AllowPatch> to specify that the existing NTER and CTER patches can be applied to it. If you create a file that adds a new patch for modifying standard amino acids, you can use <ApplyToResidue> to specify that it can be applied to the existing residues. But when everything is in one file, it makes no difference which one you use.

I'd say to go with <AllowPatch>. It's a few characters shorter, so it might reduce the file size by about 1K. :)

@jchodera
Copy link
Member Author

jchodera commented Sep 9, 2017

I'd say to go with . It's a few characters shorter, so it might reduce the file size by about 1K. :)

OK, but can you add a warning to the documentation that AllowPatch and ApplyToResidue cannot be specified simultaneously without causing (likely incomprehensible) errors?

@peastman
Copy link
Member

peastman commented Sep 9, 2017

Even better, I'll make it filter the duplicates. But you should also remove the duplicates from the file. That will reduce the size by many KB!

@jchodera
Copy link
Member Author

jchodera commented Sep 9, 2017

That will reduce the size by many KB!

Weren't you just commenting on how the 55 TB of data taken up by uncompressed xml files was no big deal because disk space is cheap now? :)

I'm working on generating the new split files now.

@peastman
Copy link
Member

peastman commented Sep 9, 2017

No, it was the 4 MB force field XML file I said wasn't significant. You should totally compress all your data! For reading them, just replace open() with gzip.open() and everything should work with no change.

@jchodera
Copy link
Member Author

jchodera commented Sep 9, 2017

No, it was the 4 MB force field XML file I said wasn't significant. You should totally compress all your data! For reading them, just replace open() with gzip.open() and everything should work with no change.

We're still struggling to figure out how to do that with the FAH cores.

@jchodera
Copy link
Member Author

jchodera commented Sep 9, 2017

OK, I've now checked that

  • the protein-only charmm36 forcefields can be converted and used to parameterize small peptides (in ParmEd nosetests)
  • the full converted charmm36 (without TIP3P) and tip3p files can be read by ForceField (but I haven't yet tried to parameterize things with these)

Here are the newly converted files:
charmm36.zip

I'm still working to add more tests to both ParmEd and the conversion scripts, but I thought I'd share the files in their current state in case they turn out to be useful (or you catch bugs that I haven't seen yet).

@peastman
Copy link
Member

We're still struggling to figure out how to do that with the FAH cores.

Yeah, that's another problem. Though isn't that really an issue on the server end, rather than the core?

@jchodera
Copy link
Member Author

Ideally not. If the server has to do the compressing/decompressing, that's enormously more expensive than having the core uncompress when reading due to WU throughput. Having transparent reading/writing of compressed XML files at the OpenMM level would allow the cost of this to be amortized over the many available donor machines.

@jchodera
Copy link
Member Author

It's possible that fahlib library actually supports transparent gzip file streaming, though. Will have to figure that out.

@jchodera
Copy link
Member Author

@peastman : I generated a membrane protein system by following the OpenMM 7 B2AR tutorial, and discovered another issue:

lski1962:test choderaj$ python test-b2ar.py 
Reading PDB file...
Reading forcefield...
Creating System...
Traceback (most recent call last):
  File "test-b2ar.py", line 11, in <module>
    system = forcefield.createSystem(pdbfile.topology)
  File "/Users/choderaj/miniconda3/lib/python3.5/site-packages/simtk/openmm/app/forcefield.py", line 1047, in createSystem
    [template, matches] = self._getResidueTemplateMatches(res, bondedToAtom, ignoreExternalBonds=ignoreExternalBonds)
  File "/Users/choderaj/miniconda3/lib/python3.5/site-packages/simtk/openmm/app/forcefield.py", line 830, in _getResidueTemplateMatches
    raise Exception('Multiple matching templates found for residue %d (%s): %s.' % (res.index+1, res.name, ', '.join(match[0].name for match in allMatches)))
Exception: Multiple matching templates found for residue 2 (TRP): TRP, DTRP.

Minimal test attached:
test-b2ar.zip

In this case, it looks like DTRP is defined in toppar/stream/prot/toppar_all36_prot_d_aminoacids.str as a D-tryptophan. Presumably, the parameters are the same as L-tryptophan, except maybe for the IC cards used to build the residue or perhaps impropers that enforce opposite chirality (if those exist?). Perhaps we should just exclude these?

Tagging @ChayaSt

@jchodera
Copy link
Member Author

I excluded that one stream file with D-amino acids and ended up with a different error:

lski1962:test-b2ar choderaj$ python test-b2ar.py 
Reading PDB file...
Reading forcefield...
Creating System...
Traceback (most recent call last):
  File "test-b2ar.py", line 11, in <module>
    system = forcefield.createSystem(pdbfile.topology, nonbondedMethod=app.PME, constraints=app.HBonds)
  File "/Users/choderaj/miniconda3/lib/python3.5/site-packages/simtk/openmm/app/forcefield.py", line 1056, in createSystem
    unmatchedResidues = _applyPatchesToMatchResidues(self, data, unmatchedResidues, bondedToAtom, ignoreExternalBonds)
  File "/Users/choderaj/miniconda3/lib/python3.5/site-packages/simtk/openmm/app/forcefield.py", line 1465, in _applyPatchesToMatchResidues
    [template, matches] = forcefield._getResidueTemplateMatches(res, bondedToAtom, patchedTemplateSignatures, ignoreExternalBonds)
  File "/Users/choderaj/miniconda3/lib/python3.5/site-packages/simtk/openmm/app/forcefield.py", line 830, in _getResidueTemplateMatches
    raise Exception('Multiple matching templates found for residue %d (%s): %s.' % (res.index+1, res.name, ', '.join(match[0].name for match in allMatches)))
Exception: Multiple matching templates found for residue 1 (VAL): VAL-NTER, VAL-NTER-DELB, VAL-NTER-FHEM, VAL-NTER-DELB-FHEM.

Is it chaining multiple patches together?

Test case attached:
test-b2ar-2.zip

@peastman
Copy link
Member

It's possible that fahlib library actually supports transparent gzip file streaming, though. Will have to figure that out.

I believe that's the case. I remember Joseph talking about how compression and/or uncompression was taking a lot of time on the server, and he was looking into switching to a less expensive compression method. So it seems that's time that's already being spent.

Exception: Multiple matching templates found for residue 1 (VAL): VAL-NTER, VAL-NTER-DELB, VAL-NTER-FHEM, VAL-NTER-DELB-FHEM.

If a residue doesn't match any template, it considers all possible combinations of single-residue patches it could apply. In this case, it's finding multiple combinations that could match, and it doesn't know which to pick. FHEM is the one I pointed out to you before that does nothing and can be applied to any residue. DELB is another one like it. They're confusing it, because it has no way to decide whether to apply those patches or not.

@jchodera
Copy link
Member Author

If a residue doesn't match any template, it considers all possible combinations of single-residue patches it could apply. In this case, it's finding multiple combinations that could match, and it doesn't know which to pick. FHEM is the one I pointed out to you before that does nothing and can be applied to any residue. DELB is another one like it. They're confusing it, because it has no way to decide whether to apply those patches or not.

I can certainly have the ResidueTemplate.apply_patch(patch) code throw an exception if the residue has not been modified, which would eliminate patches like FHEM and DELB. Let me try that now.

@peastman
Copy link
Member

The right solution is not to include those patches in the XML file in the first place. A patch that does nothing makes no sense.

@jchodera
Copy link
Member Author

That's almost, but not quite, the right solution. CHARMM permits patches that change the charges, atom types, or explicit impropers, but OpenMM cannot automatically perceive these for us. I think we want users to be able to select those patches manually if needed, but the automatic patch perception framework can't deal with them.

In light of these, it would seem we want to include all patches, but only specify patches as compatible with a residue (for purposes of automated residue x patch expansion) if they modify the topology of the residue template.

Does that sound right to you, @peastman?

@peastman
Copy link
Member

Those two patches literally do nothing. Here's the definition of one of them:

  <Patch name="FHEM">
  </Patch>

There's no benefit to including that in any form. We should remove them.

A patch that changes atom types but does nothing else is an interesting case. Assuming the two atom types both correspond to the same element, there's no way it could automatically decide whether to use the patch or not. So it could only be useful if we had some mechanism for explicitly telling it to use a patch. Currently, we don't have any such mechanism. We could consider adding one in the future, though we'd need to consider carefully what the use cases are for it.

@jchodera
Copy link
Member Author

Those two patches literally do nothing.

I think I mentioned before that they do something important in the CHARMM world:

PRES FHEM         0.00 ! FIX UP THE HEME BY DELETING UNWANTED AUTOGENERATED ANGLES
                       ! unliganded heme patch
                       ! do NOT use AUTOgenerate ANGLes DIHEdrals after this patch
DELETE ANGLE 1NA 1FE 1NC  1NB 1FE 1ND   

PRES DELB         0.00     ! patch to delete all possible base atoms
                           ! of Cyt,Gua,Ade,Thy and Ura
                           !
!note: error messages will be obtained due to atoms not present in
!residue being "deleted" by this patch
!cyt section
DELE ATOM N1   
DELE ATOM C6   
DELE ATOM H6   
DELE ATOM C2   
DELE ATOM O2   
DELE ATOM N3   
DELE ATOM C4   
DELE ATOM N4   
DELE ATOM H41  
DELE ATOM H42  
DELE ATOM C5   
DELE ATOM H5   
!gua section
DELE ATOM N9   
DELE ATOM H1   
DELE ATOM N2   
DELE ATOM H21  
DELE ATOM H22  
DELE ATOM O6   
DELE ATOM N7   
DELE ATOM C8   
DELE ATOM H8   
!ade section
DELE ATOM H2   
DELE ATOM N6   
DELE ATOM H61  
DELE ATOM H62  
!thy/ura section
DELE ATOM H3   
DELE ATOM O4   
DELE ATOM C5M  
DELE ATOM H51  
DELE ATOM H52  
DELE ATOM H53  

There's no benefit to including that in any form. We should remove them.

FHEM does nothing in the OpenMM world, since we autogenerate angles ourselves (which may be another point of discrepancy). We can detect and omit these patches that are literally blank.

I'm surprised that DELB was permitted to apply to amino acids---that doesn't seem like it should be the case.

A patch that changes atom types but does nothing else is an interesting case. Assuming the two atom types both correspond to the same element, there's no way it could automatically decide whether to use the patch or not. So it could only be useful if we had some mechanism for explicitly telling it to use a patch. Currently, we don't have any such mechanism. We could consider adding one in the future, though we'd need to consider carefully what the use cases are for it.

We definitely need a mechanism for telling ForceField to apply a patch that involves two or more residues so we can make disulfide bonds and the like, and it sounds like we will also need a mechanism to specify single-residue patches (and maybe also turn off auto-patching if needed) for cases that modify atom types or delete explicit impropers.

One such example, I believe, is patches that change only the charges of titratable residues for constant-pH dynamics.

@peastman
Copy link
Member

We definitely need a mechanism for telling ForceField to apply a patch that involves two or more residues so we can make disulfide bonds and the like

It'll detect them automatically.

@jchodera
Copy link
Member Author

It looks like I have to exclude all D-amino acids from the conversion because they match all the L-amino acids:

charmm/toppar/stream/prot/toppar_all36_prot_d_aminoacids.str

@jchodera
Copy link
Member Author

jchodera commented Oct 6, 2017

I've made the changes I think are necessary, but got bogged down converting the ffxml writing to use lxml.etree to handle Unicode and other issues. That's done now in ParmEd/ParmEd#895 but the tests need to be completed.

@jchodera
Copy link
Member Author

I'm still having trouble with the CHARMM conversion:

lski2414:charmm choderaj$ python
Python 3.6.1 |Continuum Analytics, Inc.| (default, May 11 2017, 13:04:09) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from simtk.openmm import app
>>> pdbfile = app.PDBFile('tests/POPC.pdb')
>>> ff = app.ForceField('ffxml/charmm36.xml')
>>> system = ff.createSystem(pdbfile.topology)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/choderaj/miniconda/lib/python3.6/site-packages/simtk/openmm/app/forcefield.py", line 1270, in createSystem
    force.createForce(sys, data, nonbondedMethod, nonbondedCutoff, args)
  File "/Users/choderaj/miniconda/lib/python3.6/site-packages/simtk/openmm/app/forcefield.py", line 2388, in createForce
    reverseMap[typeMap[typeValue]] = typeValue
IndexError: list assignment index out of range

I'm not quite sure what's causing this failure, but it also took several minutes for the ff.createSystem() line to run.

@jchodera
Copy link
Member Author

jchodera commented Dec 1, 2017

That last error was fixed in openmm/openmm#1915

I think this is finished now! Will reopen if we run into more trouble.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants