def save_para(self): # 检查python choose_python_path = self.choose_python_path_entry.textvariable.get() if not Check.check_python(choose_python_path): choose_python_path = "" # 检查obabel obabel_path = self.choose_obabel_path_entry.textvariable.get() if not Check.check_obabel(obabel_path): obabel_path = "" self.config.para_dict["python_path"] = choose_python_path self.config.para_dict["obabel_path"] = obabel_path # 读取原始的配置文件 with open(para_file, "r") as f: for line in f.readlines(): key = line.split("=")[0] if key == "python_path" or key == "obabel_path": continue try: value = line.split("=")[1] except IndexError: value = "" self.config.para_dict[key] = value.strip() self.config.save_para() self.top.destroy()
def extract(self, event): input_format = self.input_format.textvariable.get() input_ligands_full = self.choose_ligands_entry.entry.get() output_dir = self.extract_output_entry.entry.get() choose_num = self.complex_ligand_num_entry.entry.get() # 所有选择的路径和文件都不能为空。 if input_ligands_full == "" or output_dir == "": messagebox.showerror("错误!", "输入不能为空!") return # 不能包括空格 if Check.has_space(input_ligands_full): messagebox.showerror("错误!", "配体路径不能包含空格!") return if Check.has_space(output_dir): messagebox.showerror("错误!", "输出路径不能包含空格!") return # 选择构象要是数字 try: num = int(choose_num) except ValueError: messagebox.showerror("错误!", "提取的构象必须是数字!") return if num < 0: messagebox.showerror("错误!", "提取构象至少大于0!") return # 输出路径不存在则创建 if not os.path.exists(output_dir): os.mkdir(output_dir) input_ligands = [] # 输入的配体 if input_ligands_full.endswith(";"): # 如果是单个或者多个配体 if input_ligands_full.split(".")[-1][0:-1] != input_format: # 格式不匹配 messagebox.showerror("错误!", "配体格式不是所选格式!") return input_ligands.extend(input_ligands_full.split(";")[0:-1]) elif os.path.isdir(input_ligands_full): # 如果选择的是目录 list_file = os.listdir(input_ligands_full) for file in list_file: if file.endswith(input_format): input_ligands.append(input_ligands_full + os.sep + file) if len(input_ligands) == 0: messagebox.showerror("错误!", "所选文件夹中不包含%s格式的配体!" % input_format) return else: messagebox.showerror("错误!", "请检查输入的配体!") return for ligand in input_ligands: extract_pdbqt(ligand, output_dir, num) messagebox.showinfo("成功", "成功导入文件!")
def _vina_validate(self, event): target_folder = self.input_path_entry.textvariable.get() if not Check.check_obabel() and Check.check_python(): messagebox.showerror("错误!", "请检测obabel和mgltools的python设置!") return if not vina_validator.validate_folder(target_folder): messagebox.showerror("错误!", "无法验证所选文件夹") else: messagebox.showinfo("验证成功!", "验证%s完成!" % target_folder)
def extract_file(self, event): output_file = self.choose_output_entry.textvariable.get() extract_path = self.choose_extract_folder_entry.textvariable.get() if Check.check_path(output_file) or Check.check_path(extract_path): messagebox.showerror("错误", "路径不能有空或者有空格") return if not output_file.endswith(".txt"): messagebox.showerror("错误", "输入必须为txt文件!") return if not extract_file(output_file, extract_path): messagebox.showerror("错误!", "输入文件内容无法识别!" "具体参见命令行。") return messagebox.showinfo("成功", "成功提取配体!")
def extract_file(output_file, extract_folder): """ 读取分数文件,提取配体到指定文件夹 :param output_file: 分数文件,txt格式 :param extract_folder: 输出目录 :return 读取成功为True,否则为False """ # 判断文件所在位置 with open(output_file) as f: line1 = f.readline() # 有受体 if line1.startswith("receptor_name"): # 文件所在位置不正确 if not Check.next_path_has_pdbqt(os.path.split(output_file)[0]): print("%s所在路径不正确,请确保在受体文件夹中" % output_file) return False # 读取剩余内容 lines = f.readlines() for line in lines: receptor_name = line.split()[0] ligand_name = line.split()[1] extract_receptor_file( os.path.split(output_file)[0], receptor_name, ligand_name, extract_folder) return True # 只有配体 elif line1.startswith("ligand_name"): # 文件所在位置不正确 if not Check.path_has_pdbqt(os.path.split(output_file)[0]): print("%s所在路径不正确,请确保在配体文件夹中" % output_file) return False # 读取剩余内容 lines = f.readlines() for line in lines: ligand_name = line.split()[0] extract_ligand_file( os.path.split(output_file)[0], ligand_name, extract_folder) return True else: print("%s读取不是指定文件" % output_file) return False
def _gen_smi(self, event): if not Check.check_obabel(): messagebox.showerror("错误!", "请检查obabel路径是否配置正确!") return smi = self.input_smi_entry.textvariable.get() output_path = self.output_path_entry.textvariable.get() if Check.check_path(output_path): messagebox.showerror("错误", "输出路径不能为空或者包含空格!") return # 如果只有一个元素则表示没有[R]标签 if len(smi.split("[R]")) == 1: messagebox.showerror("错误", "%s没有[R]标签!" % smi) return gen_smi_der(smi, output_path) messagebox.showinfo("成功!", "成功生成衍生物!\n请检查后使用。")
def move_file(self, event): proteins_dir = self.choose_pdbqt_dir_entry.textvariable.get() if Check.check_path(proteins_dir): messagebox.showerror("路径不为空,不能包括空格!") return if not os.path.exists(proteins_dir): messagebox.showerror("错误", "选择文件夹不存在") return proteins2dir(proteins_dir) messagebox.showinfo("成功", "文件成功移动!")
def generate_configs(self, event): ligand = self.choose_ligand_entry.textvariable.get() proteins_dir = self.choose_receptor_entry.textvariable.get() if Check.check_path(ligand) or Check.check_path(proteins_dir): messagebox.showerror("错误", "路径不能空或者包含空格!") return if not ligand.endswith(".pdbqt"): messagebox.showerror("错误", "受体必须是pdbqt格式") return receptors_dir = [] # 如果是一个受体文件夹 if os.path.exists(proteins_dir + os.sep + "preped.pdbqt"): receptors_dir.append(proteins_dir + os.sep + "preped.pdbqt") else: for receptor in os.listdir(proteins_dir): pdbqt_file = proteins_dir + os.sep + receptor + os.sep + "preped.pdbqt" if os.path.exists(pdbqt_file): receptors_dir.append(pdbqt_file) else: print("%s中没有preped.pdbqt文件" % receptor) if len(receptors_dir) == 0: messagebox.showerror("错误", "没有检测到受体文件!") return for receptor_dir in receptors_dir: gen_config(receptor_dir, ligand) print( "------------------------------------------------------------") print("%s准备成功!" % receptor_dir) print( "------------------------------------------------------------") messagebox.showinfo("成功", "已经生成多个配置文件!")
def __get_pdb_box(pdb_file_path): """ 计算蛋白或者配体的空间中心坐标和最大立方体长宽高。 :param pdb_file_path: pdb或者pdbqt文件路径名 :return: 中心x坐标,中心y坐标,中心z坐标,长,宽,高。 """ # 保证文件存在 if not Check.check_file(pdb_file_path): print(pdb_file_path + "不存在") sys.exit() atoms_x_list = [] atoms_y_list = [] atoms_z_list = [] # 额外距离 extra_distance = 0 # 读取所有非H原子的坐标 with open(pdb_file_path) as f: lines = f.readlines() for line in lines: if line.startswith("ATOM") or line.startswith("HETATM"): if line[13:14] != "H": atoms_x_list.append(float(line[30:38])) atoms_y_list.append(float(line[38:46])) atoms_z_list.append(float(line[46:54])) if len(atoms_x_list) == 0: print("没有检测到原子") sys.exit() box_center_x = round(sum(atoms_x_list) / len(atoms_x_list), 3) box_center_y = round(sum(atoms_y_list) / len(atoms_y_list), 3) box_center_z = round(sum(atoms_z_list) / len(atoms_z_list), 3) box_length = round(max(atoms_x_list) - min(atoms_x_list), 1) + extra_distance box_width = round(max(atoms_y_list) - min(atoms_y_list), 1) + extra_distance box_height = round(max(atoms_z_list) - min(atoms_z_list), 1) + extra_distance return box_center_x, box_center_y, box_center_z, box_length, box_width, box_height
def extract_score(self, event): score_file = self.choose_scores_entry.textvariable.get() if Check.check_path(score_file): messagebox.showerror("错误", "路径不能为空或者包含空格!") return # 如果是单个pdbqt文件,弹出窗口直接显示结果。 if score_file.endswith(".pdbqt"): scores = read_scores(score_file) if len(scores) == 0: messagebox.showerror("错误", "选择的文件中没有检测到分数!") return file_name = os.path.split(score_file)[-1][0:-6] score_top = SMultiTopLevel(self.root, 600, 100, file_name).toplevel SLabel(score_top, text="当前文件:" + file_name, x=10, y=0) SLabel(score_top, text="number", x=10, y=30) SLabel(score_top, text="scores", x=10, y=60) i = 0 while i < len(scores): SLabel(score_top, text=str(i + 1), x=80 + (50 * i), y=30) SLabel(score_top, text=scores[i], x=80 + (50 * i), y=60) i += 1 # 如果是文件夹,在该文件夹中生成分数文件 elif os.path.isdir(score_file): output_file = score_file + os.sep + "scores.txt" # 如果是子目录,没有受体,只输出分数最高的 if os.listdir(score_file)[0].endswith(".pdbqt"): scores = read_folder_scores(score_file, mode=1) create_scores_file(output_file, scores, mode=1) else: scores = read_root_folder_scores(score_file, mode=1) create_scores_file(output_file, scores, mode=0) messagebox.showinfo("保存成功!", "保存分数文件到%s" % output_file) else: messagebox.showerror("输入错误", "请选择pdbqt文件或者选择文件夹!") return
def _start_convert(self, event): if not Check.check_obabel(): return if not Check.check_python(): return input_files = self.choose_ligands_entry.textvariable.get() # 判断输入内容不能包含空格 if Check.has_space(input_files): messagebox.showerror("输入错误!", "输入路径不能包含空格!") return input_format = self.input_format.textvariable.get() input_ligands = [] # 判断输入的内容 if input_files.endswith(";"): if input_files.split(".")[-1][0:-1] != input_format: messagebox.showerror("错误!", "选择的配体和输入的配体不符合!") return input_ligands.extend(input_files.split(";")[0:-1]) elif os.path.isdir(input_files): list_file = os.listdir(input_files) for file in list_file: if file.endswith(input_format): input_ligands.append(input_files + os.sep + file) if len(input_ligands) == 0: messagebox.showerror("错误!", "所选文件夹中不包含选择格式的配体!") return else: messagebox.showerror("错误!", "请检查输入的配体!") return ph = self.ph.textvariable.get() # ph不能为空 if ph == "": messagebox.showerror("错误!", "请输入pH!") return gen3d = self.gen3d.variable.get() is_minimize = self.is_minimize.variable.get() minimize = self.minimize.textvariable.get() output_format = self.output_format.textvariable.get() output_path = self.choose_output_dir_entry.textvariable.get() # 输出目录不能为空 if output_path == "" or output_path.count(" ") > 0: messagebox.showerror("输入错误!", "输出路径不能包含空格!") return if not os.path.exists(output_path): messagebox.showerror("输入错误!", "输出路径不存在!") return if input_format == output_format: messagebox.showerror("错误!", "输入和输出格式不应相等!") return output_ligands = [] for ligand in input_ligands: ligand_name = ligand.split( os.sep)[-1].split(".")[0] + "." + output_format output_ligands.append(output_path + os.sep + ligand_name) self.progress["maximum"] = len(input_ligands) # 进行格式转换 if input_format == "pdbqt": # pdbqt->other # pdbqt->pdb if output_format == "pdb": i = 0 while i < len(input_ligands): # 更改标签文字 label_text = "%i/%i" % (i + 1, len(input_ligands)) self.progress_label.label.configure(text=label_text) self.progress_label.label.update() # 更新进度条 self.progress["value"] = i + 1 self.progress.update() pdbqt_2_pdb(input_ligands[i], output_ligands[i]) i += 1 messagebox.showinfo("转换完成!", "成功将pdbqt转换成pdb!") self.progress["value"] = 0 self.progress_label.label.configure(text="没有任务") return # pdbqt->other else: # obabel转换成输出格式,先转成pdb pdb_ligands = [] for ligand in input_ligands: ligand_name = ligand.split( os.sep)[-1].split(".")[0] + ".pdb" pdb_ligands.append(output_path + os.sep + "tmp" + os.sep + ligand_name) self.progress["maximum"] = len(input_ligands) * 2 mk_output_dir(output_path + os.sep + "tmp") # 创建临时文件夹 i = 0 while i < len(input_ligands): label_text = "%i/%i" % (i + 1, len(input_ligands)) self.progress_label.label.configure(text=label_text) self.progress_label.label.update() self.progress["value"] = i + 1 self.progress.update() pdbqt_2_pdb(input_ligands[i], pdb_ligands[i]) i += 1 i = 0 while i < len(input_ligands): # 更改标签文字 label_text = "%i/%i" % (i + 1, len(input_ligands)) self.progress_label.label.configure(text=label_text) self.progress_label.label.update() # 更新进度条 self.progress["value"] = i + 1 + len(input_ligands) self.progress.update() pdb_2_other(pdb_ligands[i], output_ligands[i]) i += 1 # 删除临时pdb文件 shutil.rmtree(output_path + os.sep + "tmp") messagebox.showinfo("转换完成!", "成功将pdbqt转换%s!" % output_format) self.progress["value"] = 0 self.progress_label.label.configure(text="没有任务") return # pdb/mol2->pdbqt elif (input_format == "pdb" or input_format == "mol2") and output_format == "pdbqt": i = 0 while i < len(input_ligands): # 更改标签文字 label_text = "%i/%i" % (i + 1, len(input_ligands)) self.progress_label.label.configure(text=label_text) self.progress_label.label.update() # 更新进度条 self.progress["value"] = i + 1 + len(input_ligands) self.progress.update() pdb_mol2_2_pdbqt(input_ligands[i], output_ligands[i]) i += 1 messagebox.showinfo("转换完成!", "成功将%s转换pdbqt!" % input_format) self.progress["value"] = 0 self.progress_label.label.configure(text="没有任务") return else: # mol/smi->pdbqt if input_format == "mol" or input_format == "smi" and output_format == "pdbqt": pdb_ligands = [] for ligand in input_ligands: ligand_name = ligand.split( os.sep)[-1].split(".")[0] + ".pdb" pdb_ligands.append(output_path + os.sep + "tmp" + os.sep + ligand_name) self.progress["maximum"] = len(input_ligands) * 2 mk_output_dir(output_path + os.sep + "tmp") # 创建临时文件夹 i = 0 while i < len(input_ligands): label_text = "%i/%i" % (i + 1, len(input_ligands)) self.progress_label.label.configure(text=label_text) self.progress_label.label.update() self.progress["value"] = i + 1 self.progress.update() two_d_2_pdb(input_ligands[i], pdb_ligands[i], ph, minimize) i += 1 i = 0 while i < len(input_ligands): # 更改标签文字 label_text = "%i/%i" % (i + 1, len(input_ligands)) self.progress_label.label.configure(text=label_text) self.progress_label.label.update() # 更新进度条 self.progress["value"] = i + 1 + len(input_ligands) self.progress.update() pdb_mol2_2_pdbqt(pdb_ligands[i], output_ligands[i]) i += 1 # 删除临时pdb文件 shutil.rmtree(output_path + os.sep + "tmp") messagebox.showinfo("转换完成!", "成功将%s转换pdbqt!" % input_format) self.progress["value"] = 0 self.progress_label.label.configure(text="没有任务") return # sdf->pdbqt elif (input_format == "sdf" or input_format == "xyz") and output_format == "pdbqt": # 先转pdb pdb_ligands = [] for ligand in input_ligands: ligand_name = ligand.split( os.sep)[-1].split(".")[0] + ".pdb" pdb_ligands.append(output_path + os.sep + "tmp" + os.sep + ligand_name) self.progress["maximum"] = len(input_ligands) * 2 mk_output_dir(output_path + os.sep + "tmp") # 创建临时文件夹 i = 0 while i < len(input_ligands): label_text = "%i/%i" % (i + 1, len(input_ligands)) self.progress_label.label.configure(text=label_text) self.progress_label.label.update() self.progress["value"] = i + 1 self.progress.update() three_d_2_pdb(input_ligands[i], pdb_ligands[i], is_minimize, minimize) i += 1 i = 0 while i < len(input_ligands): # 更改标签文字 label_text = "%i/%i" % (i + 1, len(input_ligands)) self.progress_label.label.configure(text=label_text) self.progress_label.label.update() # 更新进度条 self.progress["value"] = i + 1 + len(input_ligands) self.progress.update() pdb_mol2_2_pdbqt(pdb_ligands[i], output_ligands[i]) i += 1 # 删除临时pdb文件 shutil.rmtree(output_path + os.sep + "tmp") messagebox.showinfo("转换完成!", "成功将%s转换pdbqt!" % input_format) self.progress["value"] = 0 self.progress_label.label.configure(text="没有任务") return # mol/smi/sdf/mol2/pdb/xyz->pdb/sdf/mol2/xyz else: if gen3d == "1": # 3D并最小化 if is_minimize == "1": i = 0 while i < len(input_ligands): label_text = "%s/%s" % (i + 1, len(input_ligands)) self.progress_label.label.configure( text=label_text) self.progress_label.label.update() self.progress["value"] = i + 1 self.progress.update() ob_3d_min(input_ligands[i], output_ligands[i], ph, minimize) i += 1 messagebox.showinfo( "成功!", "成功将%s转换成%s!" % (input_format, output_format)) self.progress["value"] = 0 self.progress_label.label.configure(text="没有任务") # 3D不最小化 else: i = 0 while i < len(input_ligands): label_text = "%s/%s" % (i + 1, len(input_ligands)) self.progress_label.label.configure( text=label_text) self.progress_label.label.update() self.progress["value"] = i + 1 self.progress.update() ob_3d(input_ligands[i], output_ligands[i], ph) i += 1 messagebox.showinfo( "成功!", "成功将%s转换成%s!" % (input_format, output_format)) self.progress["value"] = 0 self.progress_label.label.configure(text="没有任务") else: # 不3D并最小化 if is_minimize == "1": i = 0 while i < len(input_ligands): label_text = "%s/%s" % (i + 1, len(input_ligands)) self.progress_label.label.configure( text=label_text) self.progress_label.label.update() self.progress["value"] = i + 1 self.progress.update() ob_min(input_ligands[i], output_ligands[i], ph, minimize) i += 1 messagebox.showinfo( "成功!", "成功将%s转换成%s!" % (input_format, output_format)) self.progress["value"] = 0 self.progress_label.label.configure(text="没有任务") # 不3D也不最小化 else: i = 0 while i < len(input_ligands): label_text = "%s/%s" % (i + 1, len(input_ligands)) self.progress_label.label.configure( text=label_text) self.progress_label.label.update() self.progress["value"] = i + 1 self.progress.update() ob(input_ligands[i], output_ligands[i]) i += 1 messagebox.showinfo( "成功!", "成功将%s转换成%s!" % (input_format, output_format)) self.progress["value"] = 0 self.progress_label.label.configure(text="没有任务")
def _docking(self, event): input_ligands_full = self.choose_ligand_entry.entry.get() receptor_dir = self.choose_proteins_entry.entry.get() output_dir = self.choose_output_entry.entry.get() docking_times = self.times_entry.entry.get() # 所有选择的路径和文件都不能为空和包含空格。 if (Check.check_path(input_ligands_full) or Check.check_path(receptor_dir) or Check.check_path(output_dir) or Check.check_path(docking_times)): messagebox.showerror("输入错误", "所有参数不能为空或者包含空格") return try: times = int(docking_times) except ValueError: messagebox.showerror("错误!", "对接次数必须是数字!") return # 如果不存在输出文件夹就创建 if not os.path.exists(output_dir): os.mkdir(output_dir) input_ligands = [] # 输入的配体 if input_ligands_full.endswith(";"): # 如果是单个或者多个配体 # 必须是pdbqt文件 if input_ligands_full.split(".")[-1][0:-1] != "pdbqt": messagebox.showerror("错误!", "配体必须是pdbqt格式!") return input_ligands.extend(input_ligands_full.split(";")[0:-1]) elif os.path.isdir(input_ligands_full): # 如果选择的是目录 list_file = os.listdir(input_ligands_full) for file in list_file: if file.endswith("pdbqt"): input_ligands.append(input_ligands_full + os.sep + file) if len(input_ligands) == 0: messagebox.showerror("错误!", "所选文件夹中不包含pdbqt格式的配体!") return else: messagebox.showerror("错误!", "请检查输入的配体!") return # 输入的受体 receptors = [] # 选择了一个受体 if os.path.exists("%s" % receptor_dir + os.sep + "preped.pdbqt"): if not Check.check_config(receptor_dir): messagebox.showerror("错误!", "受体中没有config.txt文件!") return receptors.append("%s" % receptor_dir + os.sep + "preped.pdbqt") # 可能选择了多个受体 else: if not os.path.exists(receptor_dir): messagebox.showerror("错误!", "所选受体目录不存在!") return child_receptor = os.listdir(receptor_dir) for receptor in child_receptor: if os.path.exists("%s" % receptor_dir + os.sep + "%s" % receptor + os.sep + "preped.pdbqt"): if not Check.check_config("%s" % receptor_dir + os.sep + "%s" % receptor): messagebox.showwarning( "警告!", "受体%s中没有config.txt文件,将不进行对接!" % receptor) continue receptors.append("%s" % receptor_dir + os.sep + "%s" % receptor + os.sep + "preped.pdbqt") if len(receptors) == 0: messagebox.showerror("错误!", "没有受体,请检查选择的文件夹或者子文件夹中是否" "包含preped.pdbqt文件!") return self.progress["maximum"] = len(receptors) * len(input_ligands) for receptor in receptors: # 在输出目录创建受体的文件夹 output_dir_r = "%s" % output_dir + os.sep + "%s" % receptor.split( os.sep)[-2] # 读取受体中的config文件 config_files = get_config_files(os.path.split(receptor)[0]) if not os.path.exists(output_dir_r): os.mkdir(output_dir_r) for ligand in input_ligands: # 初始化循环次数 i = 0 # 更新进度条和标签 current_num = receptors.index(receptor) * len( input_ligands) + input_ligands.index(ligand) + 1 max_num = len(receptors) * len(input_ligands) label_text = "%s/%s" % (current_num, max_num) self.progress_label.label.configure(text=label_text) self.progress_label.label.update() self.progress["value"] = current_num self.progress.update() current_protein = "当前受体:%s" % receptor.split(os.sep)[-2] self.current_protein.label.configure(text=current_protein) self.current_protein.label.update() current_ligand = "当前配体:%s" % ligand.split( os.sep)[-1].split(".")[0] self.current_ligand.label.configure(text=current_ligand) self.current_ligand.label.update() current_time = "当前次数:%i" % (i + 1) self.current_time.label.configure(text=current_time) self.current_time.label.update() # 开始对接 while i < times: dock_time = i + 1 for config in config_files: ligand_basename = ligand.split( os.sep)[-1].split(".")[0] config_name = os.path.splitext(config)[0].split( os.sep)[-1] output = "%s" % output_dir_r + os.sep +\ "%s_%s_out%s.pdbqt" % (ligand_basename, config_name, dock_time) print(output) vina_dock(ligand, receptor, config, output) i += 1 messagebox.showinfo("成功!", "对接完成!") self.progress_label.label.configure(text="没有任务") self.progress_label.label.update() self.progress["value"] = 0 self.progress.update() self.current_protein.label.configure(text="") self.current_protein.label.update() self.current_ligand.label.configure(text="") self.current_ligand.label.update() self.current_time.label.configure(text="") self.current_time.label.update()
def _cal_rmsd(self, event): single_ligand = self.single_ligand_entry.textvariable.get() sec_ligands = self.sec_ligands_entry.textvariable.get() rotate_method = self.rotate_method_box.textvariable.get() reorder_method = self.reorder_method_box.textvariable.get() if Check.check_path(single_ligand) or Check.check_path(sec_ligands): messagebox.showerror("错误", "选择的文件或者路径不能为空或者包括空格!") return if not Check.check_obabel(): messagebox.showerror("错误!", "Obabel配置不正确!") return sec_ligands_path = [] # 如果选择的是一个文件 if os.path.isfile(sec_ligands): sec_ligands_path.append(sec_ligands) # 如果选的是多个文件 elif os.path.isdir(sec_ligands): list_file = os.listdir(sec_ligands) for file in list_file: if file.endswith("xyz"): sec_ligands_path.append(sec_ligands + os.sep + file) if len(sec_ligands_path) == 0: messagebox.showerror("错误!", "所选文件夹中不包含xyz的配体!") return else: messagebox.showerror("错误!请检查输入的配体!") return rmsds = {} for sec_ligand_path in sec_ligands_path: rmsd = charnley_cal_rmsd(single_ligand, sec_ligand_path, rotate_method, reorder_method) if rmsd: rmsds[os.path.split(sec_ligand_path)[-1][:-4]] = rmsd else: print("%s无法计算RMSD!" % sec_ligand_path) continue if len(rmsds) == 1: top = SMultiTopLevel(self.windows, win_x=400, win_y=100, title="RMSD结果").toplevel for ligand in rmsds: text = "%s vs %s" % (os.path.split(single_ligand)[-1] [:-4], os.path.split(ligand)[-1]) SLabel(top, text=text, x=10, y=10) text = rmsds[ligand] SLabel(top, text=text, x=10, y=50) elif len(rmsds) == 0: messagebox.showerror("错误!", "没有得到RMSD值!") return else: # 多个输出文件到目录中 output_filename = os.path.join(sec_ligands, "rmsd.txt") with open(output_filename, "w") as f: f.writelines("second_ligand\trmsd\n") for ligand in rmsds: f.write("%s\t%s\n" % (ligand, rmsds[ligand])) messagebox.showinfo("成功!", "成功导出rmsd结果到%s" % output_filename)
def _join(self, event): input_format = self.input_format.textvariable.get() input_ligands_full = self.choose_ligands_entry.entry.get() input_receptor = self.choose_proteins_entry.entry.get() output_dir = self.choose_output_entry.entry.get() choose_num = self.complex_ligand_num_entry.entry.get() remain = self.remain_ligand.variable.get() # 所有选择的路径和文件都不能为空。 if input_ligands_full == "" or input_receptor == "" or output_dir == "": messagebox.showerror("错误!", "输入不能为空!") return # 不能包括空格 if Check.has_space(input_ligands_full): messagebox.showerror("错误!", "配体路径不能包含空格!") return if Check.has_space(input_receptor): messagebox.showerror("错误!", "受体路径不能包含空格!") return if Check.has_space(output_dir): messagebox.showerror("错误!", "输出路径不能包含空格!") return # 选择构象要是数字 try: num = int(choose_num) except ValueError: messagebox.showerror("错误!", "提取的构象必须是数字!") return if num < 0: messagebox.showerror("错误!", "提取构象至少大于0!") return # 输出路径不存在则创建 if not os.path.exists(output_dir): os.mkdir(output_dir) # 受体格式必须是pdbqt if not input_receptor.endswith(".pdbqt"): messagebox.showerror("错误!", "输入的受体必须是pdbqt格式。") return input_ligands = [] # 输入的配体 if input_ligands_full.endswith(";"): # 如果是单个或者多个配体 if input_ligands_full.split(".")[-1][0:-1] != input_format: # 格式不匹配 messagebox.showerror("错误!", "配体格式不是所选格式!") return input_ligands.extend(input_ligands_full.split(";")[0:-1]) elif os.path.isdir(input_ligands_full): # 如果选择的是目录 list_file = os.listdir(input_ligands_full) for file in list_file: if file.endswith(input_format): input_ligands.append(input_ligands_full + os.sep + file) if len(input_ligands) == 0: messagebox.showerror("错误!", "所选文件夹中不包含%s格式的配体!" % input_format) return else: messagebox.showerror("错误!", "请检查输入的配体!") return # 检查路径是否正确 if not Check.check_python(): return obabel_path = Configer.get_para("obabel_path") if not Check.check_obabel(): return self.progress_label.label.configure(text="准备受体") self.progress_label.label.update() # 将受体pdbqt转成pdb input_pdb = output_dir + os.sep + input_receptor.split(".")[0].split(os.sep)[-1] + ".pdb" pdbqt_2_pdb(input_receptor, input_pdb) ligands = [] self.progress_label.label.configure(text="准备配体") self.progress_label.label.update() if input_format == "pdbqt": for ligand in input_ligands: # 是否是单个配体: with open(ligand, "r") as f: line = f.readline() if "MODEL" not in line: # 只有一个,直接转换成pdb pdb_ligand = output_dir + os.sep + ligand.split(".")[0].split(os.sep)[-1] + ".pdb" pdbqt_2_pdb(ligand, pdb_ligand) ligands.append(pdb_ligand) else: output_pdbqts = extract_pdbqt(ligand, output_dir, num) for output_pdbqt in output_pdbqts: output_pdb = output_pdbqt[:-2] pdbqt_2_pdb(output_pdbqt, output_pdb) os.remove(output_pdbqt) ligands.append(output_pdb) else: pdb_ligands = [] # 全部转换成pdb格式 for ligand in input_ligands: output_ligand = output_dir + os.sep + ligand.split(".")[0].split(os.sep)[-1] + ".pdb" ob(ligand, output_ligand) pdb_ligands.append(output_ligand) ligands = pdb_ligands # 进行复合 self.progress["maximum"] = len(ligands) for ligand in ligands: # 更新进度条 label_text = str(ligands.index(ligand) + 1) + os.sep + str(len(ligands)) self.progress_label.label.configure(text=label_text) self.progress_label.label.update() self.progress["value"] = ligands.index(ligand) + 1 self.progress.update() current_ligand = "当前配体:%s" % ligand.split(os.sep)[-1].split(".")[0] self.current_ligand.label.configure(text=current_ligand) self.current_ligand.label.update() output_name = ligand.split(os.sep)[-1].split(".")[0] + "_" + input_receptor.split(os.sep)[-1].split(".")[ 0] + ".pdb" output = output_dir + os.sep + output_name ob_join(ligand, input_pdb, output) # 如果不保留提取配体,删除提取配体 if input_format == "pdbqt" and remain == "0": for ligand in ligands: os.remove(ligand) # 删除受体 os.remove(input_pdb) messagebox.showinfo("成功!", "生成复合物成功!") self.progress_label.label.configure(text="没有任务") self.progress_label.label.update() self.progress["value"] = 0 self.progress.update() self.current_ligand.label.configure(text="") self.current_ligand.label.update()