def test_filter_ionic_liquid(): thermodynamic_state = ThermodynamicState( temperature=298.15 * unit.kelvin, pressure=101.325 * unit.kilopascal, ) # Ensure ionic liquids are filtered. data_set = PhysicalPropertyDataSet() data_set.add_properties( Density( thermodynamic_state=thermodynamic_state, phase=PropertyPhase.Liquid, value=1.0 * Density.default_unit(), uncertainty=1.0 * Density.default_unit(), source=MeasurementSource(doi=" "), substance=Substance.from_components("[Na+].[Cl-]"), ), Density( thermodynamic_state=thermodynamic_state, phase=PropertyPhase.Liquid, value=1.0 * Density.default_unit(), uncertainty=1.0 * Density.default_unit(), source=MeasurementSource(doi=" "), substance=Substance.from_components("C"), ), ) data_frame = data_set.to_pandas() filtered_frame = FilterByIonicLiquid.apply( data_frame, FilterByIonicLiquidSchema(), ) assert len(filtered_frame) == 1
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(Component(smiles_pattern), MoleFraction(mole_fraction)) return substance
def test_build_docked_coordinates_protocol(): """Tests docking a methanol molecule into alpha-Cyclodextrin.""" if not has_openeye(): pytest.skip("The `BuildDockedCoordinates` protocol requires OpenEye.") ligand_substance = Substance() ligand_substance.add_component( Component("CO", role=Component.Role.Ligand), 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_validate_data_set(): valid_property = Density( ThermodynamicState(298 * unit.kelvin, 1 * unit.atmosphere), PropertyPhase.Liquid, Substance.from_components("O"), 0.0 * unit.gram / unit.milliliter, 0.0 * unit.gram / unit.milliliter, ) data_set = PhysicalPropertyDataSet() data_set.add_properties(valid_property) data_set.validate() invalid_property = Density( ThermodynamicState(-1 * unit.kelvin, 1 * unit.atmosphere), PropertyPhase.Liquid, Substance.from_components("O"), 0.0 * unit.gram / unit.milliliter, 0.0 * unit.gram / unit.milliliter, ) with pytest.raises(AssertionError): data_set.add_properties(invalid_property) data_set.add_properties(invalid_property, validate=False) with pytest.raises(AssertionError): data_set.validate()
def estimated_reference_sets(): estimated_density = Density( thermodynamic_state=ThermodynamicState(298.15 * unit.kelvin, pressure=1.0 * unit.atmosphere), phase=PropertyPhase.Liquid, substance=Substance.from_components("O", "CC=O"), value=1.0 * unit.kilogram / unit.meter**3, uncertainty=0.1 * unit.kilogram / unit.meter**3, ) estimated_density.id = "1" estimated_enthalpy = EnthalpyOfMixing( thermodynamic_state=ThermodynamicState(298.15 * unit.kelvin, pressure=1.0 * unit.atmosphere), phase=PropertyPhase.Liquid, substance=Substance.from_components("O", "CC=O"), value=1.0 * unit.kilocalorie / unit.mole, uncertainty=0.1 * unit.kilojoule / unit.mole, ) estimated_enthalpy.id = "2" estimated_data_set = PhysicalPropertyDataSet() estimated_data_set.add_properties(estimated_density, estimated_enthalpy) reference_density = DataSetEntry( id=1, property_type="Density", temperature=298.15, pressure=101.325, value=0.001, std_error=0.0001, doi=" ", components=[ Component(smiles="O", mole_fraction=0.5), Component(smiles="CC=O", mole_fraction=0.5), ], ) reference_enthalpy = DataSetEntry( id=2, property_type="EnthalpyOfMixing", temperature=298.15, pressure=101.325, value=4.184, std_error=0.1, doi=" ", components=[ Component(smiles="O", mole_fraction=0.5), Component(smiles="CC=O", mole_fraction=0.5), ], ) reference_data_set = DataSet( id="ref", description=" ", authors=[Author(name=" ", email="*****@*****.**", institute=" ")], entries=[reference_density, reference_enthalpy], ) return estimated_data_set, reference_data_set
def test_from_pandas(): """A test to ensure that data sets may be created from pandas objects.""" thermodynamic_state = ThermodynamicState(temperature=298.15 * unit.kelvin, pressure=1.0 * unit.atmosphere) original_data_set = PhysicalPropertyDataSet() original_data_set.add_properties( Density( thermodynamic_state=thermodynamic_state, phase=PropertyPhase.Liquid, substance=Substance.from_components("CO", "O"), value=1.0 * unit.kilogram / unit.meter**3, uncertainty=1.0 * unit.kilogram / unit.meter**3, source=MeasurementSource(doi="10.5281/zenodo.596537"), ), EnthalpyOfVaporization( thermodynamic_state=thermodynamic_state, phase=PropertyPhase.from_string("Liquid + Gas"), substance=Substance.from_components("C"), value=2.0 * unit.kilojoule / unit.mole, source=MeasurementSource(reference="2"), ), DielectricConstant( thermodynamic_state=thermodynamic_state, phase=PropertyPhase.Liquid, substance=Substance.from_components("C"), value=3.0 * unit.dimensionless, source=MeasurementSource(reference="3"), ), ) data_frame = original_data_set.to_pandas() recreated_data_set = PhysicalPropertyDataSet.from_pandas(data_frame) assert len(original_data_set) == len(recreated_data_set) for original_property in original_data_set: recreated_property = next(x for x in recreated_data_set if x.id == original_property.id) assert (original_property.thermodynamic_state == recreated_property.thermodynamic_state) assert original_property.phase == recreated_property.phase assert original_property.substance == recreated_property.substance assert numpy.isclose(original_property.value, recreated_property.value) if original_property.uncertainty == UNDEFINED: assert original_property.uncertainty == recreated_property.uncertainty else: assert numpy.isclose(original_property.uncertainty, recreated_property.uncertainty) assert original_property.source.doi == recreated_property.source.doi assert original_property.source.reference == recreated_property.source.reference
def data_frame() -> pandas.DataFrame: temperatures = [298.15, 318.15] pressures = [101.325, 101.0] properties = [Density, EnthalpyOfMixing] mole_fractions = [(1.0, ), (1.0, ), (0.25, 0.75), (0.75, 0.25)] smiles = {1: [("C(F)(Cl)(Br)", ), ("C", )], 2: [("CO", "C"), ("C", "CO")]} loop_variables = [( temperature, pressure, property_type, mole_fraction, ) for temperature in temperatures for pressure in pressures for property_type in properties for mole_fraction in mole_fractions] data_entries = [] for temperature, pressure, property_type, mole_fraction in loop_variables: n_components = len(mole_fraction) for smiles_tuple in smiles[n_components]: substance = Substance() for smiles_pattern, x in zip(smiles_tuple, mole_fraction): substance.add_component(Component(smiles_pattern), MoleFraction(x)) data_entries.append( property_type( thermodynamic_state=ThermodynamicState( temperature=temperature * unit.kelvin, pressure=pressure * unit.kilopascal, ), phase=PropertyPhase.Liquid, value=1.0 * property_type.default_unit(), uncertainty=1.0 * property_type.default_unit(), source=MeasurementSource(doi=" "), substance=substance, )) data_set = PhysicalPropertyDataSet() data_set.add_properties(*data_entries) return data_set.to_pandas()
def test_solvate_existing_structure_protocol(): """Tests solvating a single methanol molecule in water.""" import mdtraj methanol_component = Component("CO") methanol_substance = Substance() methanol_substance.add_component(methanol_component, ExactAmount(1)) water_substance = Substance() water_substance.add_component(Component("O"), 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()) methanol_residue_name = build_methanol_coordinates.assigned_residue_names[ methanol_component.identifier] 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_system = mdtraj.load_pdb( solvate_coordinates.coordinate_file_path) assert solvated_system.n_residues == 10 assert solvated_system.top.residue(0).name == methanol_residue_name
def _setup_dummy_system(directory): """Generate a temporary parameterized system object.""" force_field_path = path.join(directory, "ff.json") with open(force_field_path, "w") as file: file.write(build_tip3p_smirnoff_force_field().json()) substance = Substance.from_components("O") build_coordinates = BuildCoordinatesPackmol("build_coordinates") build_coordinates.max_molecules = 10 build_coordinates.mass_density = 0.05 * unit.grams / unit.milliliters build_coordinates.substance = substance build_coordinates.execute(directory) assign_parameters = BuildSmirnoffSystem("assign_parameters") assign_parameters.force_field_path = force_field_path assign_parameters.coordinate_file_path = build_coordinates.coordinate_file_path assign_parameters.substance = substance assign_parameters.execute(directory) return ( build_coordinates.coordinate_file_path, assign_parameters.parameterized_system, )
def _build_entry(*smiles: str) -> Density: """Builds a density data entry measured at ambient conditions and for a system containing the specified smiles patterns in equal amounts. Parameters ---------- smiles The smiles to build components for. Returns ------- The built components. """ assert len(smiles) > 0 return Density( thermodynamic_state=ThermodynamicState( temperature=298.15 * unit.kelvin, pressure=101.325 * unit.kilopascal, ), phase=PropertyPhase.Liquid, value=1.0 * Density.default_unit(), uncertainty=1.0 * Density.default_unit(), source=MeasurementSource(doi=" "), substance=Substance.from_components(*smiles), )
def test_compute_dipole_moments(tmpdir): coordinate_path = get_data_filename("test/trajectories/water.pdb") trajectory_path = get_data_filename("test/trajectories/water.dcd") # Build a system object for water force_field_path = os.path.join(tmpdir, "ff.json") with open(force_field_path, "w") as file: file.write(build_tip3p_smirnoff_force_field().json()) assign_parameters = BuildSmirnoffSystem("") assign_parameters.force_field_path = force_field_path assign_parameters.coordinate_file_path = coordinate_path assign_parameters.substance = Substance.from_components("O") assign_parameters.execute(str(tmpdir)) # TODO - test gradients when TIP3P library charges added. protocol = ComputeDipoleMoments("") protocol.parameterized_system = assign_parameters.parameterized_system protocol.trajectory_path = trajectory_path protocol.execute(str(tmpdir)) assert len(protocol.dipole_moments) == 10 assert protocol.dipole_moments.value.shape[1] == 3 assert not np.allclose(protocol.dipole_moments.value, 0.0 * unit.elementary_charge * unit.nanometers)
def test_base_simulation_data_storage(): substance = Substance.from_components("C") with tempfile.TemporaryDirectory() as base_directory: data_directory = os.path.join(base_directory, "data_directory") data_object = create_dummy_simulation_data(data_directory, substance) backend_directory = os.path.join(base_directory, "storage_dir") storage = LocalFileStorage(backend_directory) storage_key = storage.store_object(data_object, data_directory) # Regenerate the data directory. os.makedirs(data_directory, exist_ok=True) assert storage.has_object(data_object) assert storage_key == storage.store_object(data_object, data_directory) retrieved_object, retrieved_directory = storage.retrieve_object( storage_key, StoredSimulationData) assert backend_directory in retrieved_directory assert data_object.json() == retrieved_object.json()
def test_compute_state_energy_gradients(tmpdir): build_tip3p_smirnoff_force_field().json(os.path.join(tmpdir, "ff.json")) _, parameterized_system = _setup_dummy_system( tmpdir, Substance.from_components("O"), 10, os.path.join(tmpdir, "ff.json")) protocol = SolvationYankProtocol("") protocol.thermodynamic_state = ThermodynamicState(298.15 * unit.kelvin, 1.0 * unit.atmosphere) protocol.gradient_parameters = [ ParameterGradientKey("vdW", "[#1]-[#8X2H2+0:1]-[#1]", "epsilon") ] gradients = protocol._compute_state_energy_gradients( mdtraj.load_dcd( get_data_filename("test/trajectories/water.dcd"), get_data_filename("test/trajectories/water.pdb"), ), parameterized_system.topology, parameterized_system.force_field.to_force_field(), True, ComputeResources(), ) assert len(gradients) == 1 assert not np.isclose(gradients[0].value, 0.0 * unit.dimensionless)
def data_frame() -> pandas.DataFrame: temperatures = [303.15, 298.15] property_types = [Density, EnthalpyOfVaporization] data_set_entries = [] def _temperature_noise(): return (numpy.random.rand() / 2.0 + 0.51) / 10.0 for temperature in temperatures: for index, property_type in enumerate(property_types): noise = _temperature_noise() noise *= 1 if index == 0 else -1 data_set_entries.append( property_type( thermodynamic_state=ThermodynamicState( temperature=temperature * unit.kelvin, pressure=101.325 * unit.kilopascal, ), phase=PropertyPhase.Liquid, value=1.0 * property_type.default_unit(), uncertainty=1.0 * property_type.default_unit(), source=MeasurementSource(doi=" "), substance=Substance.from_components("C"), ), ) data_set_entries.append( property_type( thermodynamic_state=ThermodynamicState( temperature=(temperature + noise) * unit.kelvin, pressure=101.325 * unit.kilopascal, ), phase=PropertyPhase.Liquid, value=1.0 * property_type.default_unit(), uncertainty=1.0 * property_type.default_unit(), source=MeasurementSource(doi=" "), substance=Substance.from_components("C"), ), ) data_set = PhysicalPropertyDataSet() data_set.add_properties(*data_set_entries) data_frame = data_set.to_pandas() return data_frame
def test_weight_by_mole_fraction_protocol(component_smiles, value): full_substance = Substance.from_components("C", "CC", "CCC") component = Substance.from_components(component_smiles) mole_fraction = next( iter(full_substance.get_amounts(component.components[0].identifier)) ).value with tempfile.TemporaryDirectory() as temporary_directory: weight_protocol = WeightByMoleFraction("weight") weight_protocol.value = value weight_protocol.full_substance = full_substance weight_protocol.component = component weight_protocol.execute(temporary_directory, ComputeResources()) assert weight_protocol.weighted_value == value * mole_fraction
def test_add_mole_fractions(): substance = Substance() substance.add_component(Component("C"), MoleFraction(0.5)) substance.add_component(Component("C"), MoleFraction(0.5)) assert substance.number_of_components == 1 amounts = substance.get_amounts(substance.components[0]) assert len(amounts) == 1 amount = next(iter(amounts)) assert isinstance(amount, MoleFraction) assert np.isclose(amount.value, 1.0)
def _execute(self, directory, available_resources): filtered_components = [] total_mole_fraction = 0.0 for component in self.input_substance.components: if component.role not in self.component_roles: continue filtered_components.append(component) amounts = self.input_substance.get_amounts(component) for amount in amounts: if not isinstance(amount, MoleFraction): continue total_mole_fraction += amount.value if self.expected_components != UNDEFINED and self.expected_components != len( filtered_components ): raise ValueError( f"The filtered substance does not contain the expected number of " f"components ({self.expected_components}) - {filtered_components}", ) inverse_mole_fraction = ( 1.0 if np.isclose(total_mole_fraction, 0.0) else 1.0 / total_mole_fraction ) self.filtered_substance = Substance() for component in filtered_components: amounts = self.input_substance.get_amounts(component) for amount in amounts: if isinstance(amount, MoleFraction): amount = MoleFraction(amount.value * inverse_mole_fraction) self.filtered_substance.add_component(component, amount)
def test_same_component_batching(): thermodynamic_state = ThermodynamicState(temperature=1.0 * unit.kelvin, pressure=1.0 * unit.atmosphere) data_set = PhysicalPropertyDataSet() data_set.add_properties( Density( thermodynamic_state=thermodynamic_state, substance=Substance.from_components("O", "C"), value=0.0 * unit.kilogram / unit.meter**3, ), EnthalpyOfVaporization( thermodynamic_state=thermodynamic_state, substance=Substance.from_components("O", "C"), value=0.0 * unit.kilojoule / unit.mole, ), Density( thermodynamic_state=thermodynamic_state, substance=Substance.from_components("O", "CO"), value=0.0 * unit.kilogram / unit.meter**3, ), EnthalpyOfVaporization( thermodynamic_state=thermodynamic_state, substance=Substance.from_components("O", "CO"), value=0.0 * unit.kilojoule / unit.mole, ), ) options = RequestOptions() submission = EvaluatorClient._Submission() submission.dataset = data_set submission.options = options with DaskLocalCluster() as calculation_backend: server = EvaluatorServer(calculation_backend) batches = server._batch_by_same_component(submission, "") assert len(batches) == 2 assert len(batches[0].queued_properties) == 2 assert len(batches[1].queued_properties) == 2
def data_frame() -> pandas.DataFrame: data_set = PhysicalPropertyDataSet() data_set.add_properties( Density( thermodynamic_state=ThermodynamicState( temperature=298.15 * unit.kelvin, pressure=101.325 * unit.kilopascal, ), phase=PropertyPhase.Liquid, value=1.0 * Density.default_unit(), uncertainty=1.0 * Density.default_unit(), source=MeasurementSource(doi=" "), substance=Substance.from_components("C"), ), Density( thermodynamic_state=ThermodynamicState( temperature=305.15 * unit.kelvin, pressure=101.325 * unit.kilopascal, ), phase=PropertyPhase.Liquid, value=1.0 * Density.default_unit(), uncertainty=1.0 * Density.default_unit(), source=MeasurementSource(doi=" "), substance=Substance.from_components("C"), ), Density( thermodynamic_state=ThermodynamicState( temperature=298.15 * unit.kelvin, pressure=105.325 * unit.kilopascal, ), phase=PropertyPhase.Liquid, value=1.0 * Density.default_unit(), uncertainty=1.0 * Density.default_unit(), source=MeasurementSource(doi=" "), substance=Substance.from_components("C"), ), ) return data_set.to_pandas()
def test_base_simulation_data_query(): substance_a = Substance.from_components("C") substance_b = Substance.from_components("CO") substance_full = Substance.from_components("C", "CO") substances = [substance_a, substance_b, substance_full] with tempfile.TemporaryDirectory() as base_directory: backend_directory = os.path.join(base_directory, "storage_dir") storage = LocalFileStorage(backend_directory) for substance in substances: data_directory = os.path.join(base_directory, f"{substance.identifier}") data_object = create_dummy_simulation_data(data_directory, substance) storage.store_object(data_object, data_directory) for substance in substances: substance_query = SimulationDataQuery() substance_query.substance = substance results = storage.query(substance_query) assert results is not None and len(results) == 1 assert len(next(iter(results.values()))[0]) == 3 component_query = SimulationDataQuery() component_query.substance = substance_full component_query.substance_query = SubstanceQuery() component_query.substance_query.components_only = True results = storage.query(component_query) assert results is not None and len(results) == 2
def create_substance(): test_substance = Substance() test_substance.add_component( Component("C", role=Component.Role.Solute), ExactAmount(1), ) test_substance.add_component( Component("CC", role=Component.Role.Ligand), ExactAmount(1), ) test_substance.add_component( Component("CCC", role=Component.Role.Receptor), ExactAmount(1), ) test_substance.add_component( Component("O", role=Component.Role.Solvent), MoleFraction(1.0), ) return test_substance
def dummy_complex() -> Substance: substance = Substance() substance.add_component( Component(smiles="C", role=Component.Role.Ligand), ExactAmount(1) ) substance.add_component( Component(smiles="CO", role=Component.Role.Receptor), ExactAmount(1) ) return substance
def test_calculate_reduced_potential_openmm(): substance = Substance.from_components("O") thermodynamic_state = ThermodynamicState(298 * unit.kelvin, 1.0 * unit.atmosphere) with tempfile.TemporaryDirectory() as directory: force_field_path = path.join(directory, "ff.json") with open(force_field_path, "w") as file: file.write(build_tip3p_smirnoff_force_field().json()) build_coordinates = BuildCoordinatesPackmol("build_coordinates") build_coordinates.max_molecules = 10 build_coordinates.mass_density = 0.05 * unit.grams / unit.milliliters build_coordinates.substance = substance build_coordinates.execute(directory, None) assign_parameters = BuildSmirnoffSystem("assign_parameters") assign_parameters.force_field_path = force_field_path assign_parameters.coordinate_file_path = build_coordinates.coordinate_file_path assign_parameters.substance = substance assign_parameters.execute(directory, None) reduced_potentials = OpenMMReducedPotentials("reduced_potentials") reduced_potentials.substance = substance reduced_potentials.thermodynamic_state = thermodynamic_state reduced_potentials.reference_force_field_paths = [force_field_path] reduced_potentials.system_path = assign_parameters.system_path reduced_potentials.trajectory_file_path = get_data_filename( "test/trajectories/water.dcd") reduced_potentials.coordinate_file_path = get_data_filename( "test/trajectories/water.pdb") reduced_potentials.kinetic_energies_path = get_data_filename( "test/statistics/stats_pandas.csv") reduced_potentials.high_precision = False reduced_potentials.execute(directory, ComputeResources()) assert path.isfile(reduced_potentials.statistics_file_path) final_array = StatisticsArray.from_pandas_csv( reduced_potentials.statistics_file_path) assert ObservableType.ReducedPotential in final_array
def test_evaluate_energies_openmm(): substance = Substance.from_components("O") thermodynamic_state = ThermodynamicState(298 * unit.kelvin, 1.0 * unit.atmosphere) with tempfile.TemporaryDirectory() as directory: coordinate_path, parameterized_system = _setup_dummy_system(directory) reduced_potentials = OpenMMEvaluateEnergies("") reduced_potentials.substance = substance reduced_potentials.thermodynamic_state = thermodynamic_state reduced_potentials.parameterized_system = parameterized_system reduced_potentials.trajectory_file_path = get_data_filename( "test/trajectories/water.dcd") reduced_potentials.execute(directory, ComputeResources()) assert ObservableType.ReducedPotential in reduced_potentials.output_observables assert ObservableType.PotentialEnergy in reduced_potentials.output_observables
def test_build_tleap_system(): with tempfile.TemporaryDirectory() as directory: force_field_path = path.join(directory, "ff.json") with open(force_field_path, "w") as file: file.write(TLeapForceFieldSource().json()) substance = Substance.from_components("CCCCCCCC", "O", "C(=O)N") build_coordinates = BuildCoordinatesPackmol("build_coordinates") build_coordinates.max_molecules = 9 build_coordinates.substance = substance build_coordinates.execute(directory, None) assign_parameters = BuildTLeapSystem("assign_parameters") assign_parameters.force_field_path = force_field_path assign_parameters.coordinate_file_path = build_coordinates.coordinate_file_path assign_parameters.substance = substance assign_parameters.execute(directory, None) assert path.isfile(assign_parameters.system_path)
def test_build_smirnoff_system(): with tempfile.TemporaryDirectory() as directory: force_field_path = path.join(directory, "ff.json") with open(force_field_path, "w") as file: file.write(build_tip3p_smirnoff_force_field().json()) substance = Substance.from_components("C", "O", "CO", "C(=O)N") build_coordinates = BuildCoordinatesPackmol("build_coordinates") build_coordinates.max_molecules = 8 build_coordinates.substance = substance build_coordinates.execute(directory) assign_parameters = BuildSmirnoffSystem("assign_parameters") assign_parameters.force_field_path = force_field_path assign_parameters.coordinate_file_path = build_coordinates.coordinate_file_path assign_parameters.substance = substance assign_parameters.execute(directory) assert path.isfile(assign_parameters.parameterized_system.system_path)
def simple_evaluator_data_set(): """Create a simple evaluator `PhysicalPropertyDataSet` which contains a simple binary density measurement. Returns ------- PhysicalPropertyDataSet """ evaluator_density = Density( thermodynamic_state=ThermodynamicState(298.15 * unit.kelvin, pressure=1.0 * unit.atmosphere), phase=PropertyPhase.Liquid, substance=Substance.from_components("O", "CC=O"), value=1.0 * unit.kilogram / unit.meter**3, uncertainty=0.1 * unit.kilogram / unit.meter**3, source=MeasurementSource(doi="10.1000/xyz123"), ) evaluator_density.id = "1" evaluator_data_set = PhysicalPropertyDataSet() evaluator_data_set.add_properties(evaluator_density) return evaluator_data_set
def test_build_coordinates_packmol_exact(count_exact_amount): """Tests that the build coordinate protocol behaves correctly for substances with exact amounts.""" import mdtraj substance = Substance() substance.add_component(Component("O"), MoleFraction(1.0)) substance.add_component(Component("C"), ExactAmount(1)) max_molecule = 11 if count_exact_amount else 10 build_coordinates = BuildCoordinatesPackmol("build_coordinates") build_coordinates.max_molecules = max_molecule build_coordinates.count_exact_amount = count_exact_amount build_coordinates.substance = substance with tempfile.TemporaryDirectory() as directory: build_coordinates.execute(directory) built_system = mdtraj.load_pdb(build_coordinates.coordinate_file_path) assert built_system.n_residues == 11
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(Component("O"), MoleFraction(0.41)) input_substance.add_component(Component("C"), MoleFraction(0.59)) expected_substance = Substance() expected_substance.add_component(Component("O"), MoleFraction(0.4)) expected_substance.add_component(Component("C"), MoleFraction(0.6)) substances.append((input_substance, expected_substance)) input_substance = Substance() input_substance.add_component(Component("O"), MoleFraction(0.59)) input_substance.add_component(Component("C"), MoleFraction(0.41)) expected_substance = Substance() expected_substance.add_component(Component("O"), MoleFraction(0.6)) expected_substance.add_component(Component("C"), MoleFraction(0.4)) substances.append((input_substance, expected_substance)) return substances
def default_simulation_schema(absolute_tolerance=UNDEFINED, relative_tolerance=UNDEFINED, n_molecules=2000): """Returns the default calculation schema to use when estimating this class of property from direct simulations. Parameters ---------- absolute_tolerance: pint.Quantity, optional The absolute tolerance to estimate the property to within. relative_tolerance: float The tolerance (as a fraction of the properties reported uncertainty) to estimate the property to within. n_molecules: int The number of molecules to use in the simulation. Returns ------- SimulationSchema The schema to follow when estimating this property. """ assert absolute_tolerance == UNDEFINED or relative_tolerance == UNDEFINED calculation_schema = SimulationSchema() calculation_schema.absolute_tolerance = absolute_tolerance calculation_schema.relative_tolerance = relative_tolerance use_target_uncertainty = (absolute_tolerance != UNDEFINED or relative_tolerance != UNDEFINED) # Setup the fully solvated systems. build_full_coordinates = coordinates.BuildCoordinatesPackmol( "build_solvated_coordinates") build_full_coordinates.substance = ProtocolPath("substance", "global") build_full_coordinates.max_molecules = n_molecules assign_full_parameters = forcefield.BaseBuildSystem( "assign_solvated_parameters") assign_full_parameters.force_field_path = ProtocolPath( "force_field_path", "global") assign_full_parameters.substance = ProtocolPath("substance", "global") assign_full_parameters.coordinate_file_path = ProtocolPath( "coordinate_file_path", build_full_coordinates.id) # Perform a quick minimisation of the full system to give # YANK a better starting point for its minimisation. energy_minimisation = openmm.OpenMMEnergyMinimisation( "energy_minimisation") energy_minimisation.system_path = ProtocolPath( "system_path", assign_full_parameters.id) energy_minimisation.input_coordinate_file = ProtocolPath( "coordinate_file_path", build_full_coordinates.id) equilibration_simulation = openmm.OpenMMSimulation( "equilibration_simulation") equilibration_simulation.ensemble = Ensemble.NPT equilibration_simulation.steps_per_iteration = 100000 equilibration_simulation.output_frequency = 10000 equilibration_simulation.timestep = 2.0 * unit.femtosecond equilibration_simulation.thermodynamic_state = ProtocolPath( "thermodynamic_state", "global") equilibration_simulation.system_path = ProtocolPath( "system_path", assign_full_parameters.id) equilibration_simulation.input_coordinate_file = ProtocolPath( "output_coordinate_file", energy_minimisation.id) # Create a substance which only contains the solute (e.g. for the # vacuum phase simulations). filter_solvent = miscellaneous.FilterSubstanceByRole("filter_solvent") filter_solvent.input_substance = ProtocolPath("substance", "global") filter_solvent.component_roles = [Component.Role.Solvent] filter_solute = miscellaneous.FilterSubstanceByRole("filter_solute") filter_solute.input_substance = ProtocolPath("substance", "global") filter_solute.component_roles = [Component.Role.Solute] # Setup the solute in vacuum system. build_vacuum_coordinates = coordinates.BuildCoordinatesPackmol( "build_vacuum_coordinates") build_vacuum_coordinates.substance = ProtocolPath( "filtered_substance", filter_solute.id) build_vacuum_coordinates.max_molecules = 1 assign_vacuum_parameters = forcefield.BaseBuildSystem( "assign_parameters") assign_vacuum_parameters.force_field_path = ProtocolPath( "force_field_path", "global") assign_vacuum_parameters.substance = ProtocolPath( "filtered_substance", filter_solute.id) assign_vacuum_parameters.coordinate_file_path = ProtocolPath( "coordinate_file_path", build_vacuum_coordinates.id) # Set up the protocol to run yank. run_yank = yank.SolvationYankProtocol("run_solvation_yank") run_yank.solute = ProtocolPath("filtered_substance", filter_solute.id) run_yank.solvent_1 = ProtocolPath("filtered_substance", filter_solvent.id) run_yank.solvent_2 = Substance() run_yank.thermodynamic_state = ProtocolPath("thermodynamic_state", "global") run_yank.steps_per_iteration = 500 run_yank.checkpoint_interval = 50 run_yank.solvent_1_coordinates = ProtocolPath( "output_coordinate_file", equilibration_simulation.id) run_yank.solvent_1_system = ProtocolPath("system_path", assign_full_parameters.id) run_yank.solvent_2_coordinates = ProtocolPath( "coordinate_file_path", build_vacuum_coordinates.id) run_yank.solvent_2_system = ProtocolPath("system_path", assign_vacuum_parameters.id) # Set up the group which will run yank until the free energy has been determined to within # a given uncertainty conditional_group = groups.ConditionalGroup("conditional_group") conditional_group.max_iterations = 20 if use_target_uncertainty: condition = groups.ConditionalGroup.Condition() condition.type = groups.ConditionalGroup.Condition.Type.LessThan condition.right_hand_value = ProtocolPath("target_uncertainty", "global") condition.left_hand_value = ProtocolPath( "estimated_free_energy.error", conditional_group.id, run_yank.id) conditional_group.add_condition(condition) # Define the total number of iterations that yank should run for. total_iterations = miscellaneous.MultiplyValue("total_iterations") total_iterations.value = 2000 total_iterations.multiplier = ProtocolPath("current_iteration", conditional_group.id) # Make sure the simulations gets extended after each iteration. run_yank.number_of_iterations = ProtocolPath("result", total_iterations.id) conditional_group.add_protocols(total_iterations, run_yank) # Define the full workflow schema. schema = WorkflowSchema() schema.protocol_schemas = [ build_full_coordinates.schema, assign_full_parameters.schema, energy_minimisation.schema, equilibration_simulation.schema, filter_solvent.schema, filter_solute.schema, build_vacuum_coordinates.schema, assign_vacuum_parameters.schema, conditional_group.schema, ] schema.final_value_source = ProtocolPath("estimated_free_energy", conditional_group.id, run_yank.id) calculation_schema.workflow_schema = schema return calculation_schema