You are here

[dev] Using h-bonding values in new energy term

5 posts / 0 new
Last post
[dev] Using h-bonding values in new energy term
#1

Hi all,

I'm implementing a new energy term and need to weight it based on the bb h-bonding energy of this residue and the two residues it is bonded to. It is a ContextDependentOneBodyEnergy and I have everything working except this weight. Obviously rosetta already has methods that calculate hbond_lr_bb and hbond_sr_bb. My question is - what is the best way to get the hbond energys of the residues in my energy method?

Thanks!

-Igor

Category: 
Post Situation: 
Wed, 2017-03-01 11:33
ipetrik_ambry

You have chosen a pretty complicated energy term to implement!

What you don't want to do is write an energy method that assumes that the hydrogen bonding term is on. Ideally, your energy method works even if it's the only term in the energy function. You can use the HBondSet (core::scoring::hbonds::HBondSet) to compute the set of hydrogen bonds in a structure -- you should do this inside of your EnergyMethod's setup_for_scoring function. Then you can iterate across the hydrogen bonds in the HBondSet to calculate the set of weights for the residues based on this set, and cache the weights in the Pose (similarly to how the HBondEnergy caches weights in the Pose).

You're going to have the hardest time computing derivatives because now changes to the hydrogen bond energies affect the weights for your term. You will need to use the existing functions in hbond_geom.hh to compute dEhbond / dxyz and then multiply that into a dweight / dEhbond.

Good luck!

Wed, 2017-03-01 11:49
AndrewLeaver-Fay

Thanks for the quick and informative reply Andrew!

I actually don’t currently have a need to use this method in minimization, so I’m leaving the derivative unimplemented for now. But thanks for that extra info!

Here is what I came up with in my setup_for_scoring based on your advice. Does this look reasonable? Do I have to create a new type of CacheableData and add a corresponding value to the EnergiesCacheableDataType enum if  I want to cache my weights in the pose? (Why do you recommend caching them in the pose, rather than in my EnergyMethod?)

EDIT: Updated code for the sake of posterity

//MyEnergy.cc

//...

MyEnergy::MyEnergy(
		methods::EnergyMethodOptions const & options) :
		parent(methods::EnergyMethodCreatorOP(new MyEnergyCreator)),
		options_( hbonds::HBondOptionsCOP( hbonds::HBondOptionsOP( new hbonds::HBondOptions( options.hbond_options() ) ) )) {
  // ...
}

void MyEnergy::setup_for_scoring(pose::Pose& pose,
		const ScoreFunction&) const {
	pose.update_residue_neighbors();

	//initilaize hbond-based weights;
	using EnergiesCacheableDataType::ADJ_HBOND_WEIGHT_SET;
	hbonds::HBondSetOP hbond_set( new hbonds::HBondSet( pose ) );
	/* as far as I can tell, this constructor calls fill_hbond_set() for bb only;
	 * fill_hbond_set(), in turn, runs identify_hbonds_1way () and puts the energies into the hbond_set;
	 * So at this point hbond_set should have bb-bb hbond energies for this pose
	 */
	AdjHbondWeightSetOP weight_set (new AdjHbondWeightSet(pose.n_residue())); // Created 'class AdjHbondWeightSet : public basic::datacache::CacheableData'

	for ( Size i=1; i<= hbond_set->nhbonds(); ++i ) {
		hbonds::HBondCOP hbond (hbond_set->hbond_cop (i));
		weight_set->add(pose, hbond->don_res(), hbond->energy());
		weight_set->add(pose, hbond->acc_res(), hbond->energy()); //add this energy as a weight to this residue and bonded residues
	}
	pose.energies().data().set( ADJ_HBOND_WEIGHT_SET,  weight_set ); //Added ADJ_HBOND_WEIGHT_SET EnergiesCacheableDataType
}

void MyEnergy::residue_energy(core::conformation::Residue const & rsd,
		core::pose::Pose const & pose, EnergyMap & emap) const {
      
  /* ... compute base_energy ... */

	using EnergiesCacheableDataType::ADJ_HBOND_WEIGHT_SET;
	AdjHbondWeightSet const & weight_set (static_cast< AdjHbondWeightSet const & > (pose.energies().data().get( ADJ_HBOND_WEIGHT_SET )));
	core::Real hb_weight (weight_set.get(rsd.seqpos()));

	emap[my_energy] += hb_weight * base_energy;

}

OLD CODE:


void MyEnergy::setup_for_scoring(pose::Pose& pose,
		const ScoreFunction&) const {
	pose.update_residue_neighbors();

	//initilaize hbond-based weights;
	using EnergiesCacheableDataType::HBOND_SET;
	hbonds::HBondSetOP hbond_set( new hbonds::HBondSet( *options_, pose.total_residue() ) );
	/* as far as I can tell, this constructor calls fill_hbond_set() for bb only;
	 * fill_hbond_set(), in turn, runs identify_hbonds_1way () and puts the energies into the hbond_set;
	 * So at this point hbond_set should have bb-bb hbond energies for this pose
	 */
	MyResidueWeightSet weight_set (/*...*/); // need to create a new type of CacheableData?
	
	for ( Size i=1; i<= hbond_set->nhbonds(); ++i ) {
		hbonds::HBondCOP hbond (hbond_set->hbond_cop (i));
		weight_set.add(pose, hbond->don_res(),hbond->energy());
		weight_set.add(pose, hbond->acc_res(),hbond->energy()); //add this energy as a weight to this residue and bonded residues
	}

	pose.energies().data().set( MY_RESIDUE_WEIGHT_SET, new MyResidueWeightSetOP (weight_set) ); //need to add a value to EnergiesCacheableDataType(?)
}

- Igor

Thu, 2017-03-02 16:57
ipetrik_ambry

Right -- derive a new class MyResidueWeightSet from basic::datacache::CacheableData, add a new element (e.g MY_RESIDUE_WEIGHT_SET) to the enumeration that HBOND_SET is part of (EnergiesCacheableDataType in core/scoring/EnergiesCacheableDataType.hh). Then later when you're calculating the residue_energy, you'll retrieve that cached MyResidueWeightSet object and read from it. It'll work in design. Without derivatives, it won't work in e.g. a fast_design protocol, but it sounds like you're only trying to design with it.

FWIW: you don't need the "using EnergiesCacheableDataType::HBOND_SET;" statement.

Thu, 2017-03-02 07:14
AndrewLeaver-Fay

Thanks for all the valuable info. I updated the code above for posterity for anyone else who may stumble upon it.

Thu, 2017-03-02 15:35
ipetrik_ambry