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

Some bug fixes related to building missing residues #178

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 28 additions & 6 deletions pdbfixer/pdbfixer.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ def _addAtomsToTopology(self, heavyAtomsOnly, omitUnknownMolecules):

# Create the new residue and add existing heavy atoms.

newResidue = newTopology.addResidue(residue.name, newChain, residue.id)
newResidue = newTopology.addResidue(residue.name, newChain, residue.id, residue.insertionCode)
for atom in residue.atoms():
if not heavyAtomsOnly or (atom.element is not None and atom.element != hydrogen):
if atom.name == 'OXT' and (chain.index, indexInChain+1) in self.missingResidues:
Expand Down Expand Up @@ -510,7 +510,7 @@ def _addMissingResiduesToChain(self, chain, residueNames, startPosition, endPosi

# Create the new residue.

newResidue = chain.topology.addResidue(residueName, chain, "%d" % ((firstIndex+i)%10000))
newResidue = chain.topology.addResidue(residueName, chain, "%d" % (firstIndex+i))
fraction = (i+1.0)/(numResidues+1.0)
translate = startPosition + (endPosition-startPosition)*fraction + loopHeight*math.sin(fraction*math.pi)*loopDirection
templateAtoms = list(template.topology.atoms())
Expand Down Expand Up @@ -569,7 +569,7 @@ def removeChains(self, chainIndices=None, chainIds=None):

return

def findMissingResidues(self):
def findMissingResidues(self,chainWithGapsOverride=None):
"""Find residues that are missing from the structure.

The results are stored into the missingResidues field, which is a dict. Each key is a tuple consisting of
Expand All @@ -587,13 +587,33 @@ def findMissingResidues(self):
chains = [c for c in self.topology.chains() if len(list(c.residues())) > 0]
chainWithGaps = {}

# This is PDBFixer's best guess for what might appear in a SEQRES

knownResidues = set(self.templates.keys()) | set(substitutions.keys())
for s in self.sequences:
knownResidues.update(s.residues)

# Find the sequence of each chain, with gaps for missing residues.

for chain in chains:
minResidue = min(int(r.id) for r in chain.residues())
maxResidue = max(int(r.id) for r in chain.residues())
residues = [None]*(maxResidue-minResidue+1)
if chainWithGapsOverride:
if chain.id in chainWithGapsOverride:
chainWithGaps[chain] = chainWithGapsOverride[chain.id]
continue

seqresResidues = []
for r in chain.residues():
if r.name in knownResidues:
seqresResidues.append(r)
else:
# assume that everything that follows is a ligand/water
break

if len(seqresResidues) == 0: continue
minResidue = min(int(r.id) for r in seqresResidues)
maxResidue = max(int(r.id) for r in seqresResidues)
residues = [None]*(maxResidue-minResidue+1)
for r in seqresResidues:
residues[int(r.id)-minResidue] = r.name
chainWithGaps[chain] = residues

Expand All @@ -607,6 +627,8 @@ def findMissingResidues(self):
continue
if chain in chainSequence:
continue
if chain not in chainWithGaps:
continue
for offset in range(len(sequence.residues)-len(chainWithGaps[chain])+1):
if all(a == b or b == None for a,b in zip(sequence.residues[offset:], chainWithGaps[chain])):
chainSequence[chain] = sequence
Expand Down