You are here

Custom Constraints

3 posts / 0 new
Last post
Custom Constraints
#1

Is it possible to specify a custom constraint function in PyRosetta? 

Here's a list of all the functions that we can use: https://www.rosettacommons.org/docs/latest/rosetta_basics/file_types/constraint-file

However, none of those functions match my use case.

Category: 
Post Situation: 
Wed, 2020-07-15 15:22
jinli711

Hello,

if you would like to specify a custom constraint function in pyrosetta you will need to do it on the c++ side, and then recompile your pyrosetta installation.  I reccommend looking at how the harmonic function is implemented for direction!

 

also -- do not forget that you can chain many functions together (via sumfunc) which might help you avoid writing c++ code 

~Dan

Wed, 2020-07-15 15:29
danpf

Just in case anyone else was curious about why it is impossible —or politicians have made one distrust everything read—, here is a wee experiment I did naïvely —I have not used pybind11 or boost— that proves why it is impossible.

Basically, Func is a pybind11 class with a method called func, which accepts a float and returns another based on the values it got from instantiation. It has other methods, such as dfunc gradient one.

If you pass `pyrosetta.rosetta.core.scoring.constraints.AtomPairConstraint` a python function (def or lambda) it does not like its type.

Masking its type (code snippet below, but without inheriting), ``pyrosetta.rosetta.core.scoring.constraints.AtomPairConstraint`` still dislikes its type by saying `<pyrosetta.rosetta.core.scoring.func.Func object at 0x........>` is not `pyrosetta.rosetta.core.scoring.func.Func`.
 

Making the mock function inherit `pyrosetta.rosetta.core.scoring.func.Func` makes the constraint accept it, but when calling a scorefun (or `print(con)`) with the constraint set it raises a RuntimeError as tries to call pure virtual function "Func::func", ie. we did not actually affect the C++ level it as this happens with `pyrosetta.rosetta.core.scoring.func.Func().func(2.3)`.

class fake(pyrosetta.rosetta.core.scoring.func.Func):
    def func(self, n: float): # stays virtual
        return -n
    __name__ = 'pyrosetta.rosetta.core.scoring.func.Func'
    __mro__ = pyrosetta.rosetta.core.scoring.func.Func.__mro__
    __module__ = pyrosetta.rosetta.core.scoring.func.Func.__module__
    __qualname__ = pyrosetta.rosetta.core.scoring.func.Func.__qualname__

a = pyrosetta.rosetta.core.id.AtomID(atomno_in=pose.residue(1).atom_index(' CA '), rsd_in=1)
a = pyrosetta.rosetta.core.id.AtomID(atomno_in=pose.residue(12).atom_index(' CA '), rsd_in=12)
pyrosetta.rosetta.core.scoring.constraints.AtomPairConstraint(a, b, fake())

However, it might be possible to write a pybind11-wrapped C++ object that accepts a python function and calls it as discussed in https://pybind11.readthedocs.io/en/stable/advanced/cast/functional.html —but even if doable would require compiling pyrosetta or a class with the same functionality as core::scoring::func::Func.

Fri, 2020-10-09 05:20
matteoferla