Open gusennan opened 4 years ago
Interesting... I don't think anyone has tried to configure continuous flexibility without also having discrete flexibility before.
Assuming the custom template you made has exactly one "rotamer" in it, an addition to ResidueTemplate
like this might solve the issue:
public double getRotamericDihedrals(Integer rotNum, int dihedralNum) {
if (rotNum != null) {
return getRotamericDihedrals(rotNum, dihedralNum);
}
// conformation has no rotamer number,
// so hope the template has exactly one rotamer and try to match that
var dihedralsByRotamer = rotamericDihedrals[0][0];
if (dihedralsByRotamer.length == 1) {
return dihedralsByRotamer[0][dihedralNum];
}
// don't know how to find the angle for this dihedral
throw new IllegalStateException(String.format("don't know how to find angle for dihedral"
+ "\nrotNum = %s, dihedralNum = %d, template = %s, rotamers = %d",
rotNum, dihedralNum, name, dihedralsByRotamer.length
));
}
Does this analysis change if there isn't continuous flexibility? Here's the spec of the ligand which caused the problem:
# define the ligand strand
ligand = osprey.Strand(mol, templateLib=templateLib, residues=['1', '12'])
# ligand.flexibility['6'].setLibraryRotamers('TYR').addWildTypeRotamers()
ligand.flexibility['6'].setLibraryRotamers(osprey.WILD_TYPE).addWildTypeRotamers()#.setContinuous()
ligandStrandAndFlex = [ligand]
ligandConfSpace = osprey.ConfSpace([ligandStrandAndFlex])
Wild-type here is PTR, the residue that there are 0 rotamers for, except the one that is in the structure.
If there's no flexibility of any kind at that design position, then probably that design position can just be deleted?
That's true. I think part of the issue is that the user didn't know there were no rotamers there and osprey crashed on a NPE instead. With the task-based parallelism it's a bit challenging to get at the underlying exception from python world, but that wouldn't necessarily have helped anyway without a message saying what's wrong.
With continuous flexibility the design appears to work as-is.
Ah, ok. If that's the case, then we just need a friendlier error message so the user can understand how to fix the problem.
I think that, and a general method for percolating up the Java exceptions to the user, would do the trick. These more detailed stack exceptions, such as that one shown above, are only available because whatever's throwing the exception is wrapped in a try: ... except: ...
with the ex.printStackTrace()
explicitly called, e.g:
import jpype
import jpype.imports
from jpype.types import *
import java.lang
# run BBK*
try:
scoredSequences = bbkstar.run(minimizingEcalc.tasks)
except java.lang.Exception as ex:
print(ex)
ex.printStackTrace()
The attached example crashes when the trying to use PTR in residue #6 on the ligand because there are no rotamers for PTR, even though we want to use the WT rotamer.
The field that is causing the NPE is
ResidueConf.rotamerIndex
.PTR-no-rotamers-osprey-crash.tar.gz