Without getting too detailed I would like to be able to compute all one-body and two-body energies for a set of chi angles that I have chosen (e.g. that are not from a rotamer library). I am evaluating for a set of angles for each chi rather than a single joint configuration, and would like to compute and store this set of energies. It seems like the way to go would be to build up a RotamerSets object on-the-fly as in:
1) Construct vector of RotamerSet objects
2) Create RotamerSets from the constructed rotamers
3) Create interaction graph
4) call RotamerSets::compute_energies()
I can build the vector of RotamerSet objects, but RotamerSets doesn't have a push_back or add functionality to add custom RotamerSet objects. One thing I can do is just copy the code for RotamerSets, rename it, and add the push_back functionality. If there is a better way to get at what I need without modifying core code that would be great.
Do you actually want to modify the behavior of the packer, or do you just want to score the rotamers? Because if it's just scoring of single conformations you're after, you don't need to bother with the RotamerSet(s) objects. Rosetta should be able to assign a score to any canonical amino acid conformation, even ones which aren't part of the standard rotamer library and aren't in any RotamerSet object. Just put them in a Pose and score.
If you did want to add them to a RotamerSet (say you did want to do packing, or wanted to simplify scoring a large number simultaneously), I'd take a look at the add_rotamer() function of the RotamerSet (singular) object. This should allow you to add an arbitrary rotamer to that RotamerSet. (Represented as a Residue object.) I'd recommend using the standard creation method to get the normal RotamerSets object. You can then pull out a RotamerSet for a particular position. Then add and/or remove whatever rotamers you want to with the add_rotamer() and drop_rotamer*() functions.
Thanks, I actually stumbled on this same approach after my initial post and have been working along these lines. At least I know this is the right way to do things. It isn't working yet because I wasted most of the day chasing a segfault that was the result of my not understanding owning_pointer versus access_pointer; turns out I want the later because I have an object that I occasionally want pointers to but don't want the object deleted.
To address your question, my interest is in modifying the packer, not simply scoring a single conformation.
I assume you meant "former" rather than "later" - that use case calls for the use of an owning pointer.
In general, it's best to just work with owning pointers unless 1) you call a function which already gives you back an access pointer or 2) you're working with a class structure which involves "cycles" in ownership: e.g. object A has an owning pointer to object B, which has an owning pointer to object C, which has an owning pointer back to object A. In those cases you'll need to use an access pointer somewhere to break the ownership cycle. (This means you'll need to carefully manage the lifetime of the object in some other fashion, though.)
I've implemented the suggested approach and tried validating my energies against the Dunbrack rotamer energies. In short I initialize everything and load the Dunbrack library as usual, then I modify the rotamer sets as you suggested above using the same dunbrack rotamers. My energy calculations should match up (since I effectively haven't changed anythign) but I observe some inconsistencies. The most obvious issue is that my interaction graph created on the "new" rotamer set doesn't have the same number of edges (fewer). Here are some details on what I'm doing if it sheds any light:
1) I initialized the Pose, ScoreFunction, Task (restrict to repacking) and hold these fixed throughout. I call core::pack::pack_rotamers_setup() to get the RotamerSets and InteractionGraph and compute the energies on the Dunbrack rotamers.
2) I saved off the Chi angles for all of the rotamers in RotamerSets and passed these into a function which modifies the rotamers as you suggested above.
3) I create a new InteractionGraph and compute the energies on this "new" rotamer set using the same steps in pack_rotamers_setup (e.g. prepare_sets_for_packing, create_interaction_graph, compute_energies). In these steps only the RotamerSets have been "modified", pose, task and score function are the same as previous.
I've also followed this up by saving off the Chi angles after step (3) and verifying I get what I had in step (2) and they match exactly.
One caveat to the suggested approach is that you cannot delete *all* residues in a RotamerSet, you have to leave at least one. So I'm deleting all but the first rotamer, modifying that one in-place, and then adding the rest. In fact to construct the new rotamers I simply hold a copy of this first one and modify the chi angles with ResidueOP::chi( chivec ) then add it. I'm not sure if there's any steps I'm missing.
OK, this was a dumb mistake on my part... To set the side-chain angles I was calling Residue::chi( chivec ) and passing in a vector chivec of angles. This is a simple accessor function that sets the member variable of side-chain angles, but it doesn't reorient the atoms. Residue::set_all_chi( chivec ) sets the dihedral angles and reorients the atoms.