def restraint_selection_template(topography_ligand_atoms=None, restrained_receptor_atoms=None, restrained_ligand_atoms=None, topography_regions=None): """The DSL atom selection works as expected.""" test_system = testsystems.HostGuestVacuum() topography = Topography(test_system.topology, ligand_atoms=topography_ligand_atoms) if topography_regions is not None: for region, selection in topography_regions.items(): topography.add_region(region, selection) sampler_state = states.SamplerState(positions=test_system.positions) thermodynamic_state = states.ThermodynamicState(test_system.system, temperature=300.0 * unit.kelvin) # Initialize with DSL and without processing the string raises an error. restraint = yank.restraints.Harmonic(spring_constant=2.0 * unit.kilojoule_per_mole / unit.nanometer ** 2, restrained_receptor_atoms=restrained_receptor_atoms, restrained_ligand_atoms=restrained_ligand_atoms) with nose.tools.assert_raises(yank.restraints.RestraintParameterError): restraint.restrain_state(thermodynamic_state) # After parameter determination, the indices of the restrained atoms are correct. restraint.determine_missing_parameters(thermodynamic_state, sampler_state, topography) assert len(restraint.restrained_receptor_atoms) == 14 assert len(restraint.restrained_ligand_atoms) == 30 # The bond force is configured correctly. restraint.restrain_state(thermodynamic_state) system = thermodynamic_state.system for force in system.getForces(): if isinstance(force, openmm.CustomCentroidBondForce): assert force.getBondParameters(0)[0] == (0, 1) assert len(force.getGroupParameters(0)[0]) == 14 assert len(force.getGroupParameters(1)[0]) == 30 assert isinstance(force, openmm.CustomCentroidBondForce) # We have found a force.
def test_partial_parametrization(): """The automatic restraint parametrization doesn't overwrite user values.""" # Create states and identify ligand/receptor. test_system = testsystems.HostGuestVacuum() topography = Topography(test_system.topology, ligand_atoms='resname B2') sampler_state = states.SamplerState(positions=test_system.positions) thermodynamic_state = states.ThermodynamicState(test_system.system, temperature=300.0*unit.kelvin) # Test case: (restraint_type, constructor_kwargs) boresch = dict(restrained_ligand_atoms=[130, 131, 136], K_r=1.0*unit.kilojoule_per_mole/unit.angstroms**2) test_cases = [ ('Harmonic', dict(spring_constant=2.0*unit.kilojoule_per_mole/unit.nanometer**2, restrained_receptor_atoms=[5])), ('FlatBottom', dict(well_radius=1.0*unit.angstrom, restrained_ligand_atoms=[130])), ('Boresch', boresch), ('PeriodicTorsionBoresch', boresch), ] if OpenMM73.dev_validate: test_cases.append(('RMSD', dict(restrained_ligand_atoms=[130, 131, 136], K_RMSD=1.0 * unit.kilojoule_per_mole / unit.angstroms ** 2))) for restraint_type, kwargs in test_cases: state = copy.deepcopy(thermodynamic_state) restraint = yank.restraints.create_restraint(restraint_type, **kwargs) # Test-precondition: The restraint has undefined parameters. with nose.tools.assert_raises(yank.restraints.RestraintParameterError): restraint.restrain_state(state) # The automatic parametrization maintains user values. restraint.determine_missing_parameters(state, sampler_state, topography) for parameter_name, parameter_value in kwargs.items(): assert getattr(restraint, parameter_name) == parameter_value # The rest of the parameters has been determined. restraint.get_standard_state_correction(state) # The force has been configured correctly. restraint.restrain_state(state) system = state.system for force in system.getForces(): # RadiallySymmetricRestraint between two single atoms. if isinstance(force, openmm.CustomBondForce): particle1, particle2, _ = force.getBondParameters(0) assert particle1 == restraint.restrained_receptor_atoms[0] assert particle2 == restraint.restrained_ligand_atoms[0] # Boresch restraint. elif isinstance(force, openmm.CustomCompoundBondForce): particles, _ = force.getBondParameters(0) assert particles == tuple(restraint.restrained_receptor_atoms + restraint.restrained_ligand_atoms) # RMSD restraint. elif OpenMM73.dev_validate and isinstance(force, openmm.CustomCVForce): rmsd_cv = force.getCollectiveVariable(0) particles = rmsd_cv.getParticles() assert particles == tuple(restraint.restrained_receptor_atoms + restraint.restrained_ligand_atoms)
def generate_vacuum_hostguest_proposal(current_mol_name="B2", proposed_mol_name="MOL"): """ Generate a test vacuum topology proposal, current positions, and new positions triplet from two IUPAC molecule names. Parameters ---------- current_mol_name : str, optional name of the first molecule proposed_mol_name : str, optional name of the second molecule Returns ------- topology_proposal : perses.rjmc.topology_proposal The topology proposal representing the transformation current_positions : np.array, unit-bearing The positions of the initial system new_positions : np.array, unit-bearing The positions of the new system """ from openmoltools import forcefield_generators from openmmtools import testsystems from perses.utils.openeye import smiles_to_oemol from perses.utils.data import get_data_filename host_guest = testsystems.HostGuestVacuum() unsolv_old_system, old_positions, top_old = host_guest.system, host_guest.positions, host_guest.topology ligand_topology = [res for res in top_old.residues()] current_mol = forcefield_generators.generateOEMolFromTopologyResidue( ligand_topology[1]) # guest is second residue in topology proposed_mol = smiles_to_oemol('C1CC2(CCC1(CC2)C)C') initial_smiles = oechem.OEMolToSmiles(current_mol) final_smiles = oechem.OEMolToSmiles(proposed_mol) gaff_xml_filename = get_data_filename("data/gaff.xml") forcefield = app.ForceField(gaff_xml_filename, 'tip3p.xml') forcefield.registerTemplateGenerator( forcefield_generators.gaffTemplateGenerator) solvated_system = forcefield.createSystem(top_old, removeCMMotion=False) gaff_filename = get_data_filename('data/gaff.xml') system_generator = SystemGenerator( [gaff_filename, 'amber99sbildn.xml', 'tip3p.xml'], forcefield_kwargs={ 'removeCMMotion': False, 'nonbondedMethod': app.NoCutoff }) geometry_engine = geometry.FFAllAngleGeometryEngine() proposal_engine = SmallMoleculeSetProposalEngine( [initial_smiles, final_smiles], system_generator, residue_name=current_mol_name) #generate topology proposal topology_proposal = proposal_engine.propose(solvated_system, top_old, current_mol=current_mol, proposed_mol=proposed_mol) #generate new positions with geometry engine new_positions, _ = geometry_engine.propose(topology_proposal, old_positions, beta) return topology_proposal, old_positions, new_positions
def setup_class(cls): """Shared test cases and variables.""" n_states = 3 n_steps = 5 checkpoint_interval = 2 # Test case with host guest in vacuum at 3 different positions and alchemical parameters. # ----------------------------------------------------------------------------------------- hostguest_test = testsystems.HostGuestVacuum() factory = mmtools.alchemy.AbsoluteAlchemicalFactory() alchemical_region = mmtools.alchemy.AlchemicalRegion( alchemical_atoms=range(126, 156)) hostguest_alchemical = factory.create_alchemical_system( hostguest_test.system, alchemical_region) # Translate the sampler states to be different one from each other. hostguest_sampler_states = [ mmtools.states.SamplerState(hostguest_test.positions + 10 * i * unit.nanometers) for i in range(n_states) ] # Create the three basic thermodynamic states. hostguest_thermodynamic_states = [ mmtools.states.ThermodynamicState(hostguest_alchemical, 300 * unit.kelvin) for i in range(n_states) ] # Create alchemical states at different parameter values. alchemical_states = [ mmtools.alchemy.AlchemicalState.from_system(hostguest_alchemical) for _ in range(n_states) ] for i, alchemical_state in enumerate(alchemical_states): alchemical_state.set_alchemical_parameters( float(i) / (n_states - 1)) # Create compound states. hostguest_compound_states = list() for i in range(n_states): hostguest_compound_states.append( mmtools.states.CompoundThermodynamicState( thermodynamic_state=hostguest_thermodynamic_states[i], composable_states=[alchemical_states[i]])) # Unsampled states. nonalchemical_state = mmtools.states.ThermodynamicState( hostguest_test.system, 300 * unit.kelvin) hostguest_unsampled_states = [ copy.deepcopy(nonalchemical_state), copy.deepcopy(nonalchemical_state) ] cls.hostguest_test = (hostguest_compound_states, hostguest_sampler_states, hostguest_unsampled_states) # Run a quick simulation thermodynamic_states, sampler_states, unsampled_states = copy.deepcopy( cls.hostguest_test) n_states = len(thermodynamic_states) # Remove one sampler state to verify distribution over states. sampler_states = sampler_states[:-1] # Prepare metadata for analysis. reference_state = mmtools.states.ThermodynamicState( hostguest_test.system, 300 * unit.kelvin) topography = Topography(hostguest_test.topology, ligand_atoms=range(126, 156)) metadata = { 'standard_state_correction': 4.0, 'reference_state': mmtools.utils.serialize(reference_state), 'topography': mmtools.utils.serialize(topography) } analysis_atoms = topography.ligand_atoms # Create simulation and storage file. cls.tmp_dir = tempfile.mkdtemp() storage_path = os.path.join(cls.tmp_dir, 'test_analyze.nc') move = mmtools.mcmc.LangevinDynamicsMove(n_steps=1) cls.repex = ReplicaExchange(mcmc_moves=move, number_of_iterations=n_steps) cls.reporter = Reporter(storage_path, checkpoint_interval=checkpoint_interval, analysis_particle_indices=analysis_atoms) cls.repex.create(thermodynamic_states, sampler_states, storage=cls.reporter, unsampled_thermodynamic_states=unsampled_states, metadata=metadata) # run some iterations cls.n_states = n_states cls.n_steps = n_steps cls.checkpoint_interval = checkpoint_interval cls.analysis_atoms = analysis_atoms cls.repex.run(cls.n_steps - 1) # Initial config cls.repex_name = "RepexAnalyzer"