> Maybe some pseudocode > would elucidate this. So lets look at evaluating an excluded volume potential for all nearby pairs. So we would have class NearbyPairsRestraint { NearbyPairsRestraint(PairScoreFunction *f); evaluate(da) { foreach nearby pair: f->evaluate(p0,p1, da) } }
Then we use a very general class which applies a ScoreFunc to the distance between two spheres: class SphereDistanceScore { SphereDistanceScore(FloatKey radius, ScoreFunc *f); evaluate(p0, p1) { radius= p0->radius()+p1->radius(); dist = distance(p0,p1); return f->evaluate(dist-radius); } } sf= IMP.SphereDistnaceScore(FloatKey("radius"), IMP.Harmonic(0, .1)) r= IMP.NearbyPairsRestraint(sf)
If we decided we want to move to a realish Leonard Jones potential, then we would replace the SphereDistanceScore since LJ isn't a simple function of distance. We could write a little class (ignoring the disassociation energy)
class LeonardJonesPairScore { evaluate(p0,p1) { radius = p0.get_radius()+p1.get_radius(); dist= distance(p0,p1) rat=radius/dist return rat^12-rat^6; } } Then you would just do r= IMP.NearbyPairsRestraint(particles, IMP.LeonardJonesPairScore(IMP.FloatKey("radius")))
Doing this would take a lot of work in the current framework as you would have to rewrite all the involved restraints.
Basically, by writing either a trivial PairScore or a trivial ScoreFunc you could easily generate complicated custrom restraints. Or you could choose whether you want the center distance or the sphere distance or the x distance or something else and what potential you want and compose things that way and then simply apply them to all nearby pairs or all pairs from a list or whatever.