openmm / pdbfixer

PDBFixer fixes problems in PDB files
Other
464 stars 114 forks source link

fix add missing unknown (UNK) residues error #284

Open ndonyapour opened 9 months ago

ndonyapour commented 9 months ago

Hello, I am trying to run pdbfixer with these arguments pdbfixer --pdbid=6fs0 --add-atoms=all --replace-nonstandard --add-residues --replace-nonstandard but I ran into the error below. It seems that pdbfixer tries to add a missing unknown residue to the structure.

Traceback (most recent call last):
  File "/home/donyapourn2/actions-runner/_work/workflow-inference-compiler/workflow-inference-compiler/3/envs/tests/bin/pdbfixer", line 33, in <module>
    sys.exit(load_entry_point('pdbfixer', 'console_scripts', 'pdbfixer')())
  File "/home/donyapourn2/projects/wic/pdbfixer/pdbfixer/pdbfixer.py", line 1283, in main
    fixer.addMissingAtoms()
  File "/home/donyapourn2/projects/wic/pdbfixer/pdbfixer/pdbfixer.py", line 902, in addMissingAtoms
    (newTopology, newPositions, newAtoms, existingAtomMap) = self._addAtomsToTopology(True, True)
  File "/home/donyapourn2/projects/wic/pdbfixer/pdbfixer/pdbfixer.py", line 400, in _addAtomsToTopology
    self._addMissingResiduesToChain(newChain, insertHere, startPosition, endPosition, loopDirection, residue, newAtoms, newPositions, firstIndex)
  File "/home/donyapourn2/projects/wic/pdbfixer/pdbfixer/pdbfixer.py", line 511, in _addMissingResiduesToChain
    template = self.templates[residueName]
KeyError: 'UNK'

This PR fixes this error by checking the residue before adding it.

Best, Nazanin

peastman commented 9 months ago

This doesn't fix the problem with the PDB file. It just silently ignores it. You asked it to add missing residues, but one of the missing residues has an unknown type, which means adding it is impossible.

There's no automated way to deal with this situation. It requires user input to decide how to deal with it. That's beyond the scope of the command line interface. With the programmatic interface you can tell it what to do. For example, if you want to omit unknown residues you could write.

for key, residues in copy(fixer.missingResidues).items():
    fixer.missingResidues[key] = [r for r in residues if r != 'UNK']

But maybe you instead want to replace the unknown residue with a specified one. Or skip the whole loop. Or truncate it where the unknown residue appears. The user needs to decide.

ndonyapour commented 9 months ago

Thank you for your feedback! I proposed these modifications as I considered the option of simply removing the unknown residues.

ndonyapour commented 9 months ago

I made changes to throw an error when there is an unsupported residue.