示例#1
0
    def test_remove_water_ions(self):
        # Complex file name
        fcomplex = "tests/data/pP38_lp38a_2x_complex.pdb"

        # Read OEMol molecule
        mol = oechem.OEMol()

        with oechem.oemolistream(fcomplex) as ifs:
            oechem.OEReadMolecule(ifs, mol)

        clean_system = utils.strip_water_ions(mol)

        prot, lig, wat, cofactors, lipids, metals, excipients = utils.split(
            clean_system)

        npa = prot.GetMaxAtomIdx()
        nla = lig.GetMaxAtomIdx()
        noa = excipients.GetMaxAtomIdx()
        nwa = wat.GetMaxAtomIdx()
        nlpa = lipids.GetMaxAtomIdx()
        nma = metals.GetMaxAtomIdx()
        nca = cofactors.GetMaxAtomIdx()

        self.assertEqual(npa, 5629)
        self.assertEqual(nla, 43)
        self.assertEqual(noa, 0)
        self.assertEqual(nwa, 0)
        self.assertEqual(nlpa, 0)
        self.assertEqual(nca, 0)
        self.assertEqual(nma, 0)
示例#2
0
    def test_solvation_packmol_tip3p(self):
        # Complex file name
        fcomplex = "tests/data/Bace_protein.pdb"

        # Read OEMol molecule
        mol = oechem.OEMol()

        with oechem.oemolistream(fcomplex) as ifs:
            oechem.OEReadMolecule(ifs, mol)

        # Solvate the system
        solv_complex = packmol.oesolvate(mol,
                                         density=1.0,
                                         padding_distance=10.0,
                                         distance_between_atoms=2.0,
                                         solvents='tip3p',
                                         molar_fractions='1.0',
                                         geometry='box',
                                         close_solvent=True,
                                         salt='[Na+], [Cl-]',
                                         salt_concentration=100.0,
                                         neutralize_solute=True)

        prot, lig, wat, other = utils.split(solv_complex)

        npa = prot.GetMaxAtomIdx()
        nla = lig.GetMaxAtomIdx()
        noa = other.GetMaxAtomIdx()
        nwa = wat.GetMaxAtomIdx()

        self.assertEqual(npa, 6044)
        self.assertEqual(nla, 0)
        # Ions added to excipients
        self.assertEqual(noa, 94)
        # Water molecules added
        self.assertEqual(nwa, 48279)

        box_vectors = solv_complex.GetData('box_vectors')
        box_vectors = data_utils.decodePyObj(box_vectors)
        box_vectors = box_vectors.in_units_of(unit.nanometers)

        self.assertAlmostEqual(box_vectors[0][0] / unit.nanometers,
                               8.23,
                               delta=0.01)
        self.assertEqual(box_vectors[0][1] / unit.nanometers, 0.0)
        self.assertEqual(box_vectors[0][2] / unit.nanometers, 0.0)

        self.assertAlmostEqual(box_vectors[1][1] / unit.nanometers,
                               8.23,
                               delta=0.01)
        self.assertEqual(box_vectors[1][0] / unit.nanometers, 0.0)
        self.assertEqual(box_vectors[1][2] / unit.nanometers, 0.0)

        self.assertAlmostEqual(box_vectors[2][2] / unit.nanometers,
                               8.23,
                               delta=0.01)
        self.assertEqual(box_vectors[2][0] / unit.nanometers, 0.0)
        self.assertEqual(box_vectors[2][1] / unit.nanometers, 0.0)
示例#3
0
    def test_solvation_packmol_components(self):
        # Complex file name
        fcomplex = "tests/data/Bace_protein.pdb"

        # Read OEMol molecule
        mol = oechem.OEMol()

        with oechem.oemolistream(fcomplex) as ifs:
            oechem.OEReadMolecule(ifs, mol)

        # Solvate the system
        solv_complex, solvent, salt, counter_ions = packmol.oesolvate(
            mol,
            density=1.0,
            padding_distance=10.0,
            distance_between_atoms=2.0,
            solvents='tip3p',
            molar_fractions='1.0',
            geometry='box',
            close_solvent=True,
            salt='[Na+], [Cl-]',
            salt_concentration=100.0,
            neutralize_solute=True,
            return_components=True)

        prot, lig, wat, cofactors, lipids, metals, excipients = utils.split(
            solv_complex)

        npa = prot.GetMaxAtomIdx()
        nla = lig.GetMaxAtomIdx()
        noa = excipients.GetMaxAtomIdx()
        nwa = wat.GetMaxAtomIdx()
        nlpa = lipids.GetMaxAtomIdx()
        nma = metals.GetMaxAtomIdx()
        nca = cofactors.GetMaxAtomIdx()

        self.assertEqual(npa, 6044)
        self.assertEqual(nla, 0)
        self.assertEqual(nlpa, 0)
        self.assertEqual(nca, 0)
        self.assertEqual(nma, 0)

        # The Bace system has 19 water molecules
        self.assertEqual(nwa, solvent.NumAtoms() + 19 * 3)

        # The Bace system has the TLA excipient with 14 atoms
        self.assertEqual(noa, salt.NumAtoms() + counter_ions.NumAtoms() + 14)
示例#4
0
    def test_splitter(self):
        # Complex file name
        flask_name = "tests/data/thrombin_flask.oeb"

        # Read OEMol molecule
        flask = oechem.OEMol()

        with oechem.oemolistream(flask_name) as ifs:
            oechem.OEReadMolecule(ifs, flask)

        prot, lig, wat, cofactors, lipids, metals, excipients = utils.split(
            flask, ligand_res_name='LIG')

        self.assertEqual(prot.NumAtoms(), 4686)
        self.assertEqual(lig.NumAtoms(), 52)
        self.assertEqual(wat.NumAtoms(), 33783)
        self.assertEqual(cofactors.NumAtoms(), 0)
        self.assertEqual(lipids.NumAtoms(), 0)
        self.assertEqual(metals.NumAtoms(), 0)
        self.assertEqual(excipients.NumAtoms(), 25)
示例#5
0
    def process(self, record, port):
        try:
            mdrecord = MDDataRecord(record)

            protein = mdrecord.get_protein

            protein, ligand, water, exc = oeutils.split(protein,
                                                        ligand_res_name='LIG')

            if protein.NumAtoms() == 0:
                raise ValueError("The Protein Atom number is zero")

            ligand = mdrecord.get_ligand

            if self.opt['explicit_water']:

                if self.opt['water_number'] != 0:
                    self.opt['Logger'].info(
                        "User selected number of waters: {}".format(
                            self.opt['water_number']))
                    nmax = self.opt['water_number']
                else:
                    nmax = nmax_waters(protein, ligand, self.opt['cutoff'])
            else:
                self.opt['Logger'].info("MMPBSA Explicit Water set off")
                nmax = 0

            self.nwaters.append(nmax)
            self.records.append(record)

        except Exception as e:

            print("Failed to complete", str(e), flush=True)
            self.opt['Logger'].info('Exception {} {}'.format(
                str(e), self.title))
            self.log.error(traceback.format_exc())
            self.failure.emit(record)

        return
示例#6
0
    def test_solvation_packmol_components_None(self):
        # Complex file name
        fcomplex = "tests/data/Bace_protein.pdb"

        # Read OEMol molecule
        mol = oechem.OEMol()

        with oechem.oemolistream(fcomplex) as ifs:
            oechem.OEReadMolecule(ifs, mol)

        # Solvate the system
        solv_complex, solvent, salt, counter_ions = packmol.oesolvate(
            mol,
            density=1.0,
            padding_distance=10.0,
            distance_between_atoms=2.0,
            solvents='tip3p',
            molar_fractions='1.0',
            geometry='box',
            close_solvent=True,
            salt='[Na+], [Cl-]',
            salt_concentration=0.0,
            neutralize_solute=False,
            return_components=True)

        prot, lig, wat, cofactors, lipids, metals, excipients = utils.split(
            solv_complex)

        npa = prot.GetMaxAtomIdx()
        nla = lig.GetMaxAtomIdx()

        self.assertEqual(npa, 6044)
        self.assertEqual(nla, 0)

        assert salt is None
        assert counter_ions is None
示例#7
0
    def process(self, mol, port):
        try:

            # Split the complex in components in order to apply the FF
            protein, ligand, water, excipients = oeommutils.split(
                mol, ligand_res_name=self.opt['ligand_res_name'])

            self.log.info(
                "\nComplex name: {}\nProtein atom numbers = {}\nLigand atom numbers = {}\n"
                "Water atom numbers = {}\nExcipients atom numbers = {}".format(
                    mol.GetTitle(), protein.NumAtoms(), ligand.NumAtoms(),
                    water.NumAtoms(), excipients.NumAtoms()))

            # Unique prefix name used to output parametrization files
            self.opt['prefix_name'] = mol.GetTitle()

            oe_mol_list = []
            par_mol_list = []

            # Apply FF to the Protein
            if protein.NumAtoms():
                oe_mol_list.append(protein)
                protein_structure = utils.applyffProtein(protein, self.opt)
                par_mol_list.append(protein_structure)

            # Apply FF to the ligand
            if ligand.NumAtoms():
                oe_mol_list.append(ligand)
                ligand_structure = utils.applyffLigand(ligand, self.opt)
                par_mol_list.append(ligand_structure)

            # Apply FF to water molecules
            if water.NumAtoms():
                oe_mol_list.append(water)
                water_structure = utils.applyffWater(water, self.opt)
                par_mol_list.append(water_structure)

            # Apply FF to the excipients
            if excipients.NumAtoms():
                excipient_structure = utils.applyffExcipients(
                    excipients, self.opt)
                par_mol_list.append(excipient_structure)

                # The excipient order is set equal to the order in related
                # parmed structure to avoid possible atom index mismatching
                excipients = oeommutils.openmmTop_to_oemol(
                    excipient_structure.topology,
                    excipient_structure.positions,
                    verbose=False)
                oechem.OEPerceiveBondOrders(excipients)
                oe_mol_list.append(excipients)

            # Build the overall Parmed structure
            complex_structure = parmed.Structure()

            for struc in par_mol_list:
                complex_structure = complex_structure + struc

            complx = oe_mol_list[0].CreateCopy()
            num_atom_system = complx.NumAtoms()

            for idx in range(1, len(oe_mol_list)):
                oechem.OEAddMols(complx, oe_mol_list[idx])
                num_atom_system += oe_mol_list[idx].NumAtoms()

            if not num_atom_system == complex_structure.topology.getNumAtoms():
                oechem.OEThrow.Fatal(
                    "Parmed and OE topologies mismatch atom number error")

            complx.SetTitle(mol.GetTitle())

            # Set Parmed structure box_vectors
            is_periodic = True
            try:
                vec_data = pack_utils.PackageOEMol.getData(complx,
                                                           tag='box_vectors')
                vec = pack_utils.PackageOEMol.decodePyObj(vec_data)
                complex_structure.box_vectors = vec
            except:
                is_periodic = False
                self.log.warn(
                    "System has been parametrize without periodic box vectors for vacuum simulation"
                )

            # Attach the Parmed structure to the complex
            packed_complex = pack_utils.PackageOEMol.pack(
                complx, complex_structure)

            # Attach the reference positions to the complex
            ref_positions = complex_structure.positions
            packedpos = pack_utils.PackageOEMol.encodePyObj(ref_positions)
            packed_complex.SetData(oechem.OEGetTag('OEMDDataRefPositions'),
                                   packedpos)

            # Set atom serial numbers, Ligand name and HETATM flag
            # oechem.OEPerceiveResidues(packed_complex, oechem.OEPreserveResInfo_SerialNumber)
            for at in packed_complex.GetAtoms():
                thisRes = oechem.OEAtomGetResidue(at)
                thisRes.SetSerialNumber(at.GetIdx())
                if thisRes.GetName() == 'UNL':
                    # thisRes.SetName("LIG")
                    thisRes.SetHetAtom(True)
                oechem.OEAtomSetResidue(at, thisRes)

            if packed_complex.GetMaxAtomIdx(
            ) != complex_structure.topology.getNumAtoms():
                raise ValueError(
                    "OEMol complex and Parmed structure mismatch atom numbers")

            # Check if it is possible to create the OpenMM System
            if is_periodic:
                complex_structure.createSystem(
                    nonbondedMethod=app.CutoffPeriodic,
                    nonbondedCutoff=10.0 * unit.angstroms,
                    constraints=app.HBonds,
                    removeCMMotion=False)
            else:
                complex_structure.createSystem(nonbondedMethod=app.NoCutoff,
                                               constraints=app.HBonds,
                                               removeCMMotion=False)

            self.success.emit(packed_complex)
        except Exception as e:
            # Attach error message to the molecule that failed
            self.log.error(traceback.format_exc())
            mol.SetData('error', str(e))
            # Return failed mol
            self.failure.emit(mol)

        return
示例#8
0
    def process(self, mol, port):
        try:
            if port == 'system_port':

                # Remove from solution water and ions
                if self.opt['remove_explicit_solvent']:
                    mol = oeommutils.strip_water_ions(mol)

                self.system = mol
                self.check_system = True
                return

            if self.check_system:
                num_conf = 0

                try:
                    lig_id = mol.GetData("IDTag")
                    name = 'p' + self.system.GetTitle() + '_' + lig_id
                except:
                    name = 'p' + self.system.GetTitle() + '_l' + mol.GetTitle(
                    )[0:12] + '_' + str(self.count)

                for conf in mol.GetConfs():
                    conf_mol = oechem.OEMol(conf)
                    complx = self.system.CreateCopy()
                    oechem.OEAddMols(complx, conf_mol)

                    # Split the complex in components
                    protein, ligand, water, excipients = oeommutils.split(
                        complx)

                    # If the protein does not contain any atom emit a failure
                    if not protein.NumAtoms(
                    ):  # Error: protein molecule is empty
                        oechem.OEThrow.Fatal(
                            "The protein molecule does not contains atoms")

                    # If the ligand does not contain any atom emit a failure
                    if not ligand.NumAtoms(
                    ):  # Error: ligand molecule is empty
                        oechem.OEThrow.Fatal(
                            "The Ligand molecule does not contains atoms")

                    # Check if the ligand is inside the binding site. Cutoff distance 3A
                    if not oeommutils.check_shell(ligand, protein, 3):
                        oechem.OEThrow.Fatal(
                            "The ligand is probably outside the protein binding site"
                        )

                    # Removing possible clashes between the ligand and water or excipients
                    if water.NumAtoms():
                        water_del = oeommutils.delete_shell(ligand,
                                                            water,
                                                            1.5,
                                                            in_out='in')

                    if excipients.NumAtoms():
                        excipient_del = oeommutils.delete_shell(ligand,
                                                                excipients,
                                                                1.5,
                                                                in_out='in')

                    # Reassemble the complex
                    new_complex = protein.CreateCopy()
                    oechem.OEAddMols(new_complex, ligand)
                    if excipients.NumAtoms():
                        oechem.OEAddMols(new_complex, excipient_del)
                    if water.NumAtoms():
                        oechem.OEAddMols(new_complex, water_del)

                    name_c = name
                    if mol.GetMaxConfIdx() > 1:
                        name_c = name + '_c' + str(num_conf)
                    new_complex.SetData(oechem.OEGetTag('IDTag'), name_c)
                    new_complex.SetTitle(name_c)
                    num_conf += 1
                    self.success.emit(new_complex)
                self.count += 1

        except Exception as e:
            # Attach error message to the molecule that failed
            self.log.error(traceback.format_exc())
            mol.SetData('error', str(e))
            # Return failed mol
            self.failure.emit(mol)

        return
示例#9
0
    def test_compex_prep_split_floe(self):
        workfloe = WorkFloeWrapper.get_workfloe(os.path.join(
            FLOES_DEV_DIR, "Complex_prep.py"),
                                                run_timeout=43200,
                                                queue_timeout=2000)

        ligand_file = DatasetWrapper.get_dataset(
            os.path.join(FILE_DIR, "MCL1_lig26.oeb"))

        protein_file = DatasetWrapper.get_dataset(
            os.path.join(FILE_DIR, "MCL1_protein_ACE_NMA_caps.pdb"))

        output_file = OutputDatasetWrapper(extension=".oedb")
        fail_output_file = OutputDatasetWrapper(extension=".oedb")

        workfloe.start({
            "promoted": {
                "ligands": ligand_file.identifier,
                "protein": protein_file.identifier,
                "out": output_file.identifier,
                "fail": fail_output_file.identifier
            }
        })

        self.assertWorkFloeComplete(workfloe)

        fail_ifs = oechem.oeifstream()
        records_fail = []

        for rec_fail in read_records(fail_ifs):
            records_fail.append(rec_fail)
        fail_ifs.close()

        count = len(records_fail)
        # The fail record must be empty
        self.assertEqual(count, 0)

        ifs = oeifstream(output_file.path)
        records = []

        for rec in read_records(ifs):
            records.append(rec)
        ifs.close()

        count = len(records)
        # Check the out record list
        self.assertEqual(count, 1)

        # Each record should have the MD record interface
        for record in records:

            mdrecord = MDDataRecord(record)

            self.assertTrue(record.has_value(Fields.flaskid))
            self.assertTrue(record.has_value(Fields.title))
            self.assertTrue(record.has_value(Fields.ligand))
            self.assertTrue(record.has_value(Fields.protein))
            self.assertTrue(record.has_value(Fields.primary_molecule))
            self.assertTrue(record.has_value(Fields.flask))
            self.assertTrue(record.has_value(Fields.md_stages))
            self.assertTrue(record.has_value(Fields.pmd_structure))

            self.assertEqual(mdrecord.get_flask_id, 0)
            self.assertEqual(mdrecord.get_title, "pMCL1_l26")
            self.assertEqual(record.get_value(Fields.ligand).NumAtoms(), 43)
            self.assertEqual(record.get_value(Fields.protein).NumAtoms(), 2432)

            complx = mdrecord.get_flask
            protein_split, ligand_split, water, excipients = oeommutils.split(
                complx)
            self.assertEqual(protein_split.NumAtoms(), 2432)
            self.assertEqual(ligand_split.NumAtoms(), 43)
            self.assertEqual(water.NumAtoms(), 20022)
            self.assertEqual(excipients.NumAtoms(), 17)

            stages = mdrecord.get_stages
            self.assertEqual(len(stages), 1)

            stage = stages[0]

            self.assertTrue(stage.has_value(Fields.stage_name))
            self.assertTrue(stage.has_value(Fields.mddata))

            self.assertEqual(stage.get_value(Fields.stage_type), "SETUP")

            top_mol = mdrecord.get_stage_topology()
            self.assertEqual(top_mol.NumAtoms(), complx.NumAtoms())
示例#10
0
    def process(self, solvated_system, port):

        try:
            opt = dict(self.opt)

            # Extract the solvated ligand and the solvated complex
            solvated_ligand = solvated_system[0]
            solvated_complex = solvated_system[1]

            # Update cube simulation parameters with the eventually molecule SD tags
            new_args = {dp.GetTag(): dp.GetValue() for dp in oechem.OEGetSDDataPairs(solvated_ligand) if dp.GetTag() in
                        ["temperature", "pressure"]}
            if new_args:
                for k in new_args:
                    try:
                        new_args[k] = float(new_args[k])
                    except:
                        pass
                self.log.info("Updating parameters for molecule: {}\n{}".format(solvated_ligand.GetTitle(), new_args))
                opt.update(new_args)

            # Extract the MD data
            mdData_ligand = data_utils.MDData(solvated_ligand)
            solvated_ligand_structure = mdData_ligand.structure

            mdData_complex = data_utils.MDData(solvated_complex)
            solvated_complex_structure = mdData_complex.structure

            # Create the solvated OpenMM systems
            solvated_complex_omm_sys = solvated_complex_structure.createSystem(nonbondedMethod=app.PME,
                                                                               nonbondedCutoff=opt['nonbondedCutoff'] * unit.angstroms,
                                                                               constraints=app.HBonds,
                                                                               removeCMMotion=False)

            solvated_ligand_omm_sys = solvated_ligand_structure.createSystem(nonbondedMethod=app.PME,
                                                                             nonbondedCutoff=opt['nonbondedCutoff'] * unit.angstroms,
                                                                             constraints=app.HBonds,
                                                                             removeCMMotion=False)

            # Write out all the required files and set-run the Yank experiment
            with TemporaryDirectory() as output_directory:

                opt['Logger'].info("Output Directory {}".format(output_directory))

                solvated_complex_structure_fn = os.path.join(output_directory, "complex.pdb")
                solvated_complex_structure.save(solvated_complex_structure_fn, overwrite=True)

                solvated_ligand_structure_fn = os.path.join(output_directory, "solvent.pdb")
                solvated_ligand_structure.save(solvated_ligand_structure_fn, overwrite=True)

                solvated_complex_omm_serialized = XmlSerializer.serialize(solvated_complex_omm_sys)
                solvated_complex_omm_serialized_fn = os.path.join(output_directory, "complex.xml")
                solvated_complex_f = open(solvated_complex_omm_serialized_fn, 'w')
                solvated_complex_f.write(solvated_complex_omm_serialized)
                solvated_complex_f.close()

                solvated_ligand_omm_serialized = XmlSerializer.serialize(solvated_ligand_omm_sys)
                solvated_ligand_omm_serialized_fn = os.path.join(output_directory, "solvent.xml")
                solvated_ligand_f = open(solvated_ligand_omm_serialized_fn, 'w')
                solvated_ligand_f.write(solvated_ligand_omm_serialized)
                solvated_ligand_f.close()

                # Build the Yank Experiment
                yaml_builder = ExperimentBuilder(yank_binding_template.format(
                    verbose='yes' if opt['verbose'] else 'no',
                    minimize='yes' if opt['minimize'] else 'no',
                    output_directory=output_directory,
                    timestep=opt['timestep'],
                    nsteps_per_iteration=opt['nsteps_per_iteration'],
                    number_iterations=opt['iterations'],
                    temperature=opt['temperature'],
                    pressure=opt['pressure'],
                    complex_pdb_fn=solvated_complex_structure_fn,
                    complex_xml_fn=solvated_complex_omm_serialized_fn,
                    solvent_pdb_fn=solvated_ligand_structure_fn,
                    solvent_xml_fn=solvated_ligand_omm_serialized_fn,
                    restraints=opt['restraints'],
                    ligand_resname=opt['ligand_resname']))

                # Run Yank
                yaml_builder.run_experiments()

                exp_dir = os.path.join(output_directory, "experiments")

                DeltaG_binding, dDeltaG_binding, DeltaH, dDeltaH = yankutils.analyze_directory(exp_dir)

                protein, ligand, water, excipients = oeommutils.split(solvated_ligand,
                                                                      ligand_res_name=opt['ligand_resname'])
                # Add result to the extracted ligand in kcal/mol
                oechem.OESetSDData(ligand, 'DG_yank_binding', str(DeltaG_binding))
                oechem.OESetSDData(ligand, 'dG_yank_binding', str(dDeltaG_binding))

            self.success.emit(ligand)

        except Exception as e:
            # Attach an error message to the molecule that failed
            self.log.error(traceback.format_exc())
            solvated_system[1].SetData('error', str(e))
            # Return failed mol
            self.failure.emit(solvated_system[1])

        return 
示例#11
0
    def process(self, solvated_system, port):

        try:
            # The copy of the dictionary option as local variable
            # is necessary to avoid filename collisions due to
            # the parallel cube processes
            opt = dict(self.opt)

            # Split the complex in components
            protein, solute, water, excipients = oeommutils.split(solvated_system, ligand_res_name='LIG')

            # Update cube simulation parameters with the eventually molecule SD tags
            new_args = {dp.GetTag(): dp.GetValue() for dp in oechem.OEGetSDDataPairs(solute) if dp.GetTag() in
                        ["temperature", "pressure"]}

            if new_args:
                for k in new_args:
                    try:
                        new_args[k] = float(new_args[k])
                    except:
                        pass
                self.log.info("Updating parameters for molecule: {}\n{}".format(solute.GetTitle(), new_args))
                opt.update(new_args)

            # Extract the MD data
            mdData = data_utils.MDData(solvated_system)
            solvated_structure = mdData.structure

            # Extract the ligand parmed structure
            solute_structure = solvated_structure.split()[0][0]
            solute_structure.box = None

            # Set the ligand title
            solute.SetTitle(solvated_system.GetTitle())

            # Create the solvated and vacuum system
            solvated_omm_sys = solvated_structure.createSystem(nonbondedMethod=app.PME,
                                                               nonbondedCutoff=opt['nonbondedCutoff'] * unit.angstroms,
                                                               constraints=app.HBonds,
                                                               removeCMMotion=False)

            solute_omm_sys = solute_structure.createSystem(nonbondedMethod=app.NoCutoff,
                                                           constraints=app.HBonds,
                                                           removeCMMotion=False)

            # This is a note from:
            # https://github.com/MobleyLab/SMIRNOFF_paper_code/blob/e5012c8fdc4570ca0ec750f7ab81dd7102e813b9/scripts/create_input_files.py#L114
            # Fix switching function.
            for force in solvated_omm_sys.getForces():
                if isinstance(force, openmm.NonbondedForce):
                    force.setUseSwitchingFunction(True)
                    force.setSwitchingDistance((opt['nonbondedCutoff'] - 1.0) * unit.angstrom)

            # Write out all the required files and set-run the Yank experiment
            with TemporaryDirectory() as output_directory:

                opt['Logger'].info("Output Directory {}".format(output_directory))

                solvated_structure_fn = os.path.join(output_directory, "solvated.pdb")
                solvated_structure.save(solvated_structure_fn, overwrite=True)

                solute_structure_fn = os.path.join(output_directory, "solute.pdb")
                solute_structure.save(solute_structure_fn, overwrite=True)

                solvated_omm_sys_serialized = XmlSerializer.serialize(solvated_omm_sys)
                solvated_omm_sys_serialized_fn = os.path.join(output_directory, "solvated.xml")
                solvated_f = open(solvated_omm_sys_serialized_fn, 'w')
                solvated_f.write(solvated_omm_sys_serialized)
                solvated_f.close()

                solute_omm_sys_serialized = XmlSerializer.serialize(solute_omm_sys)
                solute_omm_sys_serialized_fn = os.path.join(output_directory, "solute.xml")
                solute_f = open(solute_omm_sys_serialized_fn, 'w')
                solute_f.write(solute_omm_sys_serialized)
                solute_f.close()

                # Build the Yank Experiment
                yaml_builder = ExperimentBuilder(yank_solvation_template.format(
                                                 verbose='yes' if opt['verbose'] else 'no',
                                                 minimize='yes' if opt['minimize'] else 'no',
                                                 output_directory=output_directory,
                                                 timestep=opt['timestep'],
                                                 nsteps_per_iteration=opt['nsteps_per_iteration'],
                                                 number_iterations=opt['iterations'],
                                                 temperature=opt['temperature'],
                                                 pressure=opt['pressure'],
                                                 solvated_pdb_fn=solvated_structure_fn,
                                                 solvated_xml_fn=solvated_omm_sys_serialized_fn,
                                                 solute_pdb_fn=solute_structure_fn,
                                                 solute_xml_fn=solute_omm_sys_serialized_fn))

                # Run Yank
                yaml_builder.run_experiments()

                exp_dir = os.path.join(output_directory, "experiments")

                # Calculate solvation free energy, solvation Enthalpy and their errors
                DeltaG_solvation, dDeltaG_solvation, DeltaH, dDeltaH = yankutils.analyze_directory(exp_dir)

                # # Add result to the original molecule in kcal/mol
                oechem.OESetSDData(solute, 'DG_yank_solv', str(DeltaG_solvation))
                oechem.OESetSDData(solute, 'dG_yank_solv', str(dDeltaG_solvation))

            # Emit the ligand
            self.success.emit(solute)

        except Exception as e:
            # Attach an error message to the molecule that failed
            self.log.error(traceback.format_exc())
            solvated_system.SetData('error', str(e))
            # Return failed mol
            self.failure.emit(solvated_system)

        return