def test_solvate_existing_structure_protocol(): """Tests solvating a single methanol molecule in water.""" methanol_substance = Substance() methanol_substance.add_component(Substance.Component('CO'), Substance.ExactAmount(1)) water_substance = Substance() water_substance.add_component(Substance.Component('O'), Substance.MoleFraction(1.0)) with tempfile.TemporaryDirectory() as temporary_directory: build_methanol_coordinates = BuildCoordinatesPackmol('build_methanol') build_methanol_coordinates.max_molecules = 1 build_methanol_coordinates.substance = methanol_substance build_methanol_coordinates.execute(temporary_directory, ComputeResources()) solvate_coordinates = SolvateExistingStructure('solvate_methanol') solvate_coordinates.max_molecules = 9 solvate_coordinates.substance = water_substance solvate_coordinates.solute_coordinate_file = build_methanol_coordinates.coordinate_file_path solvate_coordinates.execute(temporary_directory, ComputeResources()) solvated_pdb = PDBFile(solvate_coordinates.coordinate_file_path) assert solvated_pdb.topology.getNumResidues() == 10
def test_multiple_amounts(): substance = Substance() substance.add_component(Substance.Component('[Na+]'), Substance.MoleFraction(0.75)) substance.add_component(Substance.Component('[Na+]'), Substance.ExactAmount(1)) substance.add_component(Substance.Component('[Cl-]'), Substance.MoleFraction(0.25)) substance.add_component(Substance.Component('[Cl-]'), Substance.ExactAmount(1)) assert substance.number_of_components == 2 sodium_amounts = substance.get_amounts('[Na+]') chlorine_amounts = substance.get_amounts('[Cl-]') assert len(sodium_amounts) == 2 assert len(chlorine_amounts) == 2 molecule_counts = substance.get_molecules_per_component(6) assert len(molecule_counts) == 2 assert molecule_counts['[Na+]'] == 4 assert molecule_counts['[Cl-]'] == 2
def test_filter_by_smiles(): """A test to ensure that data sets may be filtered by which smiles their measured properties contain.""" methanol_substance = Substance() methanol_substance.add_component(Substance.Component('CO'), Substance.MoleFraction(1.0)) ethanol_substance = Substance() ethanol_substance.add_component(Substance.Component('CCO'), Substance.MoleFraction(1.0)) property_a = create_dummy_property(Density) property_a.substance = methanol_substance property_b = create_dummy_property(Density) property_b.substance = ethanol_substance data_set = PhysicalPropertyDataSet() data_set.properties[methanol_substance.identifier] = [property_a] data_set.properties[ethanol_substance.identifier] = [property_b] data_set.filter_by_smiles('CO') assert data_set.number_of_properties == 1 assert methanol_substance.identifier in data_set.properties assert ethanol_substance.identifier not in data_set.properties
def create_dummy_substance(number_of_components, elements=None): """Creates a substance with a given number of components, each containing the specified elements. Parameters ---------- number_of_components : int The number of components to add to the substance. elements : list of str The elements that each component should containt. Returns ------- Substance The created substance. """ if elements is None: elements = ['C'] substance = Substance() mole_fraction = 1.0 / number_of_components for index in range(number_of_components): smiles_pattern = ''.join(elements * (index + 1)) substance.add_component(Substance.Component(smiles_pattern), Substance.MoleFraction(mole_fraction)) return substance
def create_substance(): test_substance = Substance() test_substance.add_component(Substance.Component('C', role=Substance.ComponentRole.Solute), Substance.ExactAmount(1)) test_substance.add_component(Substance.Component('CC', role=Substance.ComponentRole.Ligand), Substance.ExactAmount(1)) test_substance.add_component(Substance.Component('CCC', role=Substance.ComponentRole.Receptor), Substance.ExactAmount(1)) test_substance.add_component(Substance.Component('O', role=Substance.ComponentRole.Solvent), Substance.MoleFraction(1.0)) return test_substance
def test_density_dielectric_merging(): substance = Substance() substance.add_component(Substance.Component(smiles='C'), Substance.MoleFraction()) density = Density(thermodynamic_state=ThermodynamicState(temperature=298*unit.kelvin, pressure=1*unit.atmosphere), phase=PropertyPhase.Liquid, substance=substance, value=10*unit.gram/unit.mole, uncertainty=1*unit.gram/unit.mole) dielectric = DielectricConstant(thermodynamic_state=ThermodynamicState(temperature=298*unit.kelvin, pressure=1*unit.atmosphere), phase=PropertyPhase.Liquid, substance=substance, value=10*unit.gram/unit.mole, uncertainty=1*unit.gram/unit.mole) density_schema = density.get_default_workflow_schema('SimulationLayer', WorkflowOptions()) dielectric_schema = dielectric.get_default_workflow_schema('SimulationLayer', WorkflowOptions()) density_metadata = Workflow.generate_default_metadata(density, 'smirnoff99Frosst-1.1.0.offxml', []) dielectric_metadata = Workflow.generate_default_metadata(density, 'smirnoff99Frosst-1.1.0.offxml', []) density_workflow = Workflow(density, density_metadata) density_workflow.schema = density_schema dielectric_workflow = Workflow(dielectric, dielectric_metadata) dielectric_workflow.schema = dielectric_schema workflow_graph = WorkflowGraph('') workflow_graph.add_workflow(density_workflow) workflow_graph.add_workflow(dielectric_workflow) merge_order_a = graph.topological_sort(density_workflow.dependants_graph) merge_order_b = graph.topological_sort(dielectric_workflow.dependants_graph) for protocol_id_A, protocol_id_B in zip(merge_order_a, merge_order_b): if protocol_id_A.find('extract_traj') < 0 and protocol_id_A.find('extract_stats') < 0: assert density_workflow.protocols[protocol_id_A].schema.json() == \ dielectric_workflow.protocols[protocol_id_B].schema.json() else: assert density_workflow.protocols[protocol_id_A].schema.json() != \ dielectric_workflow.protocols[protocol_id_B].schema.json()
def test_add_mole_fractions(): substance = Substance() substance.add_component(Substance.Component('C'), Substance.MoleFraction(0.5)) substance.add_component(Substance.Component('C'), Substance.MoleFraction(0.5)) assert substance.number_of_components == 1 amounts = substance.get_amounts('C') assert len(amounts) == 1 amount = next(iter(amounts)) assert isinstance(amount, Substance.MoleFraction) assert np.isclose(amount.value, 1.0)
def _build_input_output_substances(): """Builds sets if input and expected substances for the `test_build_coordinate_composition` test. Returns ------- list of tuple of Substance and Substance A list of input and expected substances. """ # Start with some easy cases substances = [ (Substance.from_components('O'), Substance.from_components('O')), (Substance.from_components('O', 'C'), Substance.from_components('O', 'C')), (Substance.from_components('O', 'C', 'CO'), Substance.from_components('O', 'C', 'CO')) ] # Handle some cases where rounding will need to occur. input_substance = Substance() input_substance.add_component(Substance.Component('O'), Substance.MoleFraction(0.41)) input_substance.add_component(Substance.Component('C'), Substance.MoleFraction(0.59)) expected_substance = Substance() expected_substance.add_component(Substance.Component('O'), Substance.MoleFraction(0.4)) expected_substance.add_component(Substance.Component('C'), Substance.MoleFraction(0.6)) substances.append((input_substance, expected_substance)) input_substance = Substance() input_substance.add_component(Substance.Component('O'), Substance.MoleFraction(0.59)) input_substance.add_component(Substance.Component('C'), Substance.MoleFraction(0.41)) expected_substance = Substance() expected_substance.add_component(Substance.Component('O'), Substance.MoleFraction(0.6)) expected_substance.add_component(Substance.Component('C'), Substance.MoleFraction(0.4)) substances.append((input_substance, expected_substance)) return substances
def test_data_class_retrieval(): """A simple test to that force fields can be stored and retrieved using the local storage backend.""" substance = Substance() substance.add_component(Substance.Component('C'), Substance.MoleFraction(1.0)) with tempfile.TemporaryDirectory() as base_directory_path: storage_directory = os.path.join(base_directory_path, 'storage') local_storage = LocalFileStorage(storage_directory) for data_class_type in [DummyDataClass1, DummyDataClass2]: data_directory = os.path.join(base_directory_path, data_class_type.__name__) os.makedirs(data_directory, exist_ok=True) data_object = data_class_type() data_object.substance = substance local_storage.store_simulation_data(data_object, data_directory) retrieved_data_directories = local_storage.retrieve_simulation_data( substance, data_class=BaseStoredData) assert len(retrieved_data_directories[substance.identifier]) == 2 retrieved_data_directories = local_storage.retrieve_simulation_data( substance, data_class=DummyDataClass1) assert len(retrieved_data_directories[substance.identifier]) == 1 retrieved_data_directories = local_storage.retrieve_simulation_data( substance, data_class=DummyDataClass2) assert len(retrieved_data_directories[substance.identifier]) == 1 retrieved_data_directories = local_storage.retrieve_simulation_data( substance, data_class=StoredSimulationData) assert len(retrieved_data_directories[substance.identifier]) == 0
def test_build_docked_coordinates_protocol(): """Tests docking a methanol molecule into alpha-Cyclodextrin.""" ligand_substance = Substance() ligand_substance.add_component( Substance.Component('CO', role=Substance.ComponentRole.Ligand), Substance.ExactAmount(1)) # TODO: This test could likely be made substantially faster # by storing the binary prepared receptor. Would this # be in breach of any oe license terms? with tempfile.TemporaryDirectory() as temporary_directory: build_docked_coordinates = BuildDockedCoordinates('build_methanol') build_docked_coordinates.ligand_substance = ligand_substance build_docked_coordinates.number_of_ligand_conformers = 5 build_docked_coordinates.receptor_coordinate_file = get_data_filename( 'test/molecules/acd.mol2') build_docked_coordinates.execute(temporary_directory, ComputeResources()) docked_pdb = PDBFile( build_docked_coordinates.docked_complex_coordinate_path) assert docked_pdb.topology.getNumResidues() == 2
def test_ligand_receptor_yank_protocol(): full_substance = Substance() full_substance.add_component( Substance.Component(smiles='c1ccccc1', role=Substance.ComponentRole.Receptor), Substance.ExactAmount(1)) full_substance.add_component( Substance.Component(smiles='C', role=Substance.ComponentRole.Ligand), Substance.ExactAmount(1)) full_substance.add_component( Substance.Component(smiles='O', role=Substance.ComponentRole.Solvent), Substance.MoleFraction(1.0)) solute_substance = Substance() solute_substance.add_component( Substance.Component(smiles='C', role=Substance.ComponentRole.Ligand), Substance.ExactAmount(1)) solute_substance.add_component( Substance.Component(smiles='O', role=Substance.ComponentRole.Solvent), Substance.MoleFraction(1.0)) thermodynamic_state = ThermodynamicState(temperature=298.15 * unit.kelvin, pressure=1.0 * unit.atmosphere) with tempfile.TemporaryDirectory() as directory: with temporarily_change_directory(directory): force_field_path = 'ff.json' with open(force_field_path, 'w') as file: file.write(build_tip3p_smirnoff_force_field().json()) complex_coordinate_path, complex_system_path = _setup_dummy_system( 'full', full_substance, 3, force_field_path) ligand_coordinate_path, ligand_system_path = _setup_dummy_system( 'ligand', solute_substance, 2, force_field_path) run_yank = LigandReceptorYankProtocol('yank') run_yank.substance = full_substance run_yank.thermodynamic_state = thermodynamic_state run_yank.number_of_iterations = 1 run_yank.steps_per_iteration = 1 run_yank.checkpoint_interval = 1 run_yank.verbose = True run_yank.setup_only = True run_yank.ligand_residue_name = 'TMP' run_yank.receptor_residue_name = 'TMP' run_yank.solvated_ligand_coordinates = ligand_coordinate_path run_yank.solvated_ligand_system = ligand_system_path run_yank.solvated_complex_coordinates = complex_coordinate_path run_yank.solvated_complex_system = complex_system_path run_yank.force_field_path = force_field_path result = run_yank.execute('', ComputeResources()) assert not isinstance(result, PropertyEstimatorException)
def test_solvation_yank_protocol(solvent_smiles): full_substance = Substance() full_substance.add_component( Substance.Component(smiles='CO', role=Substance.ComponentRole.Solute), Substance.ExactAmount(1)) full_substance.add_component( Substance.Component(smiles=solvent_smiles, role=Substance.ComponentRole.Solvent), Substance.MoleFraction(1.0)) solvent_substance = Substance() solvent_substance.add_component( Substance.Component(smiles=solvent_smiles, role=Substance.ComponentRole.Solvent), Substance.MoleFraction(1.0)) solute_substance = Substance() solute_substance.add_component( Substance.Component(smiles='CO', role=Substance.ComponentRole.Solute), Substance.ExactAmount(1)) thermodynamic_state = ThermodynamicState(temperature=298.15 * unit.kelvin, pressure=1.0 * unit.atmosphere) with tempfile.TemporaryDirectory() as directory: with temporarily_change_directory(directory): force_field_path = 'ff.json' with open(force_field_path, 'w') as file: file.write(build_tip3p_smirnoff_force_field().json()) solvated_coordinate_path, solvated_system_path = _setup_dummy_system( 'full', full_substance, 2, force_field_path) vacuum_coordinate_path, vacuum_system_path = _setup_dummy_system( 'vacuum', solute_substance, 1, force_field_path) run_yank = SolvationYankProtocol('yank') run_yank.solute = solute_substance run_yank.solvent_1 = solvent_substance run_yank.solvent_2 = Substance() run_yank.thermodynamic_state = thermodynamic_state run_yank.number_of_iterations = 1 run_yank.steps_per_iteration = 1 run_yank.checkpoint_interval = 1 run_yank.verbose = True run_yank.setup_only = True run_yank.solvent_1_coordinates = solvated_coordinate_path run_yank.solvent_1_system = solvated_system_path run_yank.solvent_2_coordinates = vacuum_coordinate_path run_yank.solvent_2_system = vacuum_system_path run_yank.electrostatic_lambdas_1 = [1.00] run_yank.steric_lambdas_1 = [1.00] run_yank.electrostatic_lambdas_2 = [1.00] run_yank.steric_lambdas_2 = [1.00] result = run_yank.execute('', ComputeResources()) assert not isinstance(result, PropertyEstimatorException)
def _create_data_set(): """Create a small data set of three properties taken from the FreeSolv data set: https://github.com/mobleylab/FreeSolv. Returns ------- PhysicalPropertyDataSet The data set of three select FreeSolv properties. """ butan_1_ol = Substance() butan_1_ol.add_component( Substance.Component('CCCCO', role=Substance.ComponentRole.Solute), Substance.ExactAmount(1)) butan_1_ol.add_component( Substance.Component('O', role=Substance.ComponentRole.Solvent), Substance.MoleFraction(1.0)) butan_1_ol_property = SolvationFreeEnergy( thermodynamic_state=ThermodynamicState(298.15 * unit.kelvin, 1.0 * unit.atmosphere), phase=PropertyPhase.Liquid, substance=butan_1_ol, value=-4.72 * unit.kilocalorie / unit.mole, uncertainty=0.6 * unit.kilocalorie / unit.mole, source=MeasurementSource(doi=' 10.1021/ct050097l')) methyl_propanoate = Substance() methyl_propanoate.add_component( Substance.Component('CCC(=O)OC', role=Substance.ComponentRole.Solute), Substance.ExactAmount(1)) methyl_propanoate.add_component( Substance.Component('O', role=Substance.ComponentRole.Solvent), Substance.MoleFraction(1.0)) methyl_propanoate_property = SolvationFreeEnergy( thermodynamic_state=ThermodynamicState(298.15 * unit.kelvin, 1.0 * unit.atmosphere), phase=PropertyPhase.Liquid, substance=methyl_propanoate, value=-2.93 * unit.kilocalorie / unit.mole, uncertainty=0.6 * unit.kilocalorie / unit.mole, source=MeasurementSource(doi=' 10.1021/ct050097l')) benzamide = Substance() benzamide.add_component( Substance.Component('c1ccc(cc1)C(=O)N', role=Substance.ComponentRole.Solute), Substance.ExactAmount(1)) benzamide.add_component( Substance.Component('O', role=Substance.ComponentRole.Solvent), Substance.MoleFraction(1.0)) benzamide_property = SolvationFreeEnergy( thermodynamic_state=ThermodynamicState(298.15 * unit.kelvin, 1.0 * unit.atmosphere), phase=PropertyPhase.Liquid, substance=benzamide, value=-11.0 * unit.kilocalorie / unit.mole, uncertainty=0.2 * unit.kilocalorie / unit.mole, source=MeasurementSource(doi=' 10.1021/ct050097l')) data_set = PhysicalPropertyDataSet() data_set.properties[butan_1_ol.identifier] = [butan_1_ol_property] data_set.properties[methyl_propanoate.identifier] = [ methyl_propanoate_property ] data_set.properties[benzamide.identifier] = [benzamide_property] return data_set
def test_base_simulation_protocols(): """Tests that the commonly chain build coordinates, assigned topology, energy minimise and perform simulation are able to work together without raising an exception.""" water_substance = Substance() water_substance.add_component(Substance.Component(smiles='O'), Substance.MoleFraction()) thermodynamic_state = ThermodynamicState(298 * unit.kelvin, 1 * unit.atmosphere) with tempfile.TemporaryDirectory() as temporary_directory: force_field_source = build_tip3p_smirnoff_force_field() force_field_path = path.join(temporary_directory, 'ff.offxml') with open(force_field_path, 'w') as file: file.write(force_field_source.json()) build_coordinates = BuildCoordinatesPackmol('') # Set the maximum number of molecules in the system. build_coordinates.max_molecules = 10 # and the target density (the default 1.0 g/ml is normally fine) build_coordinates.mass_density = 0.05 * unit.grams / unit.milliliters # and finally the system which coordinates should be generated for. build_coordinates.substance = water_substance # Build the coordinates, creating a file called output.pdb result = build_coordinates.execute(temporary_directory, None) assert not isinstance(result, PropertyEstimatorException) # Assign some smirnoff force field parameters to the # coordinates print('Assigning some parameters.') assign_force_field_parameters = BuildSmirnoffSystem('') assign_force_field_parameters.force_field_path = force_field_path assign_force_field_parameters.coordinate_file_path = path.join( temporary_directory, 'output.pdb') assign_force_field_parameters.substance = water_substance result = assign_force_field_parameters.execute(temporary_directory, None) assert not isinstance(result, PropertyEstimatorException) # Do a simple energy minimisation print('Performing energy minimisation.') energy_minimisation = RunEnergyMinimisation('') energy_minimisation.input_coordinate_file = path.join( temporary_directory, 'output.pdb') energy_minimisation.system_path = assign_force_field_parameters.system_path result = energy_minimisation.execute(temporary_directory, ComputeResources()) assert not isinstance(result, PropertyEstimatorException) npt_equilibration = RunOpenMMSimulation('npt_equilibration') npt_equilibration.ensemble = Ensemble.NPT npt_equilibration.steps_per_iteration = 20 # Debug settings. npt_equilibration.output_frequency = 2 # Debug settings. npt_equilibration.thermodynamic_state = thermodynamic_state npt_equilibration.input_coordinate_file = path.join( temporary_directory, 'minimised.pdb') npt_equilibration.system_path = assign_force_field_parameters.system_path result = npt_equilibration.execute(temporary_directory, ComputeResources()) assert not isinstance(result, PropertyEstimatorException) extract_density = ExtractAverageStatistic('extract_density') extract_density.statistics_type = ObservableType.Density extract_density.statistics_path = path.join(temporary_directory, 'statistics.csv') result = extract_density.execute(temporary_directory, ComputeResources()) assert not isinstance(result, PropertyEstimatorException) extract_dielectric = ExtractAverageDielectric('extract_dielectric') extract_dielectric.thermodynamic_state = thermodynamic_state extract_dielectric.input_coordinate_file = path.join( temporary_directory, 'input.pdb') extract_dielectric.trajectory_path = path.join(temporary_directory, 'trajectory.dcd') extract_dielectric.system_path = assign_force_field_parameters.system_path result = extract_dielectric.execute(temporary_directory, ComputeResources()) assert not isinstance(result, PropertyEstimatorException) extract_uncorrelated_trajectory = ExtractUncorrelatedTrajectoryData( 'extract_traj') extract_uncorrelated_trajectory.statistical_inefficiency = extract_density.statistical_inefficiency extract_uncorrelated_trajectory.equilibration_index = extract_density.equilibration_index extract_uncorrelated_trajectory.input_coordinate_file = path.join( temporary_directory, 'input.pdb') extract_uncorrelated_trajectory.input_trajectory_path = path.join( temporary_directory, 'trajectory.dcd') result = extract_uncorrelated_trajectory.execute( temporary_directory, ComputeResources()) assert not isinstance(result, PropertyEstimatorException) extract_uncorrelated_statistics = ExtractUncorrelatedStatisticsData( 'extract_stats') extract_uncorrelated_statistics.statistical_inefficiency = extract_density.statistical_inefficiency extract_uncorrelated_statistics.equilibration_index = extract_density.equilibration_index extract_uncorrelated_statistics.input_statistics_path = path.join( temporary_directory, 'statistics.csv') result = extract_uncorrelated_statistics.execute( temporary_directory, ComputeResources()) assert not isinstance(result, PropertyEstimatorException)