From 5948e64e18706c0b131521977e849bec9505b9b7 Mon Sep 17 00:00:00 2001 From: Ramji Date: Tue, 10 Sep 2019 15:58:03 -0700 Subject: [PATCH 01/19] Add Rhodium support --- .gitignore | 1 + nanome_docking/Docking.py | 27 ++- nanome_docking/_DockingCalculationsRhodium.py | 123 ++++++++++ nanome_docking/_DockingMenuRhodium.py | 225 ++++++++++++++++++ nanome_docking/_docking_menu_rhodium.json | 1 + 5 files changed, 370 insertions(+), 7 deletions(-) create mode 100644 nanome_docking/_DockingCalculationsRhodium.py create mode 100644 nanome_docking/_DockingMenuRhodium.py create mode 100644 nanome_docking/_docking_menu_rhodium.json diff --git a/.gitignore b/.gitignore index 24c0589..b915a3b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ nanome_docking.egg-info/ dist/ *.pyc nanome +nanome_docking/Rh_x64.exe diff --git a/nanome_docking/Docking.py b/nanome_docking/Docking.py index 6812ea7..9b22844 100644 --- a/nanome_docking/Docking.py +++ b/nanome_docking/Docking.py @@ -1,7 +1,9 @@ import nanome from ._DockingCalculations import DockingCalculations as Smina from ._DockingCalculationsAutodock4 import DockingCalculations as Autodock4 +from ._DockingCalculationsRhodium import DockingCalculations as Rhodium from ._DockingMenu import DockingMenu +from ._DockingMenuRhodium import DockingMenuRhodium import sys __metaclass__ = type @@ -9,7 +11,7 @@ class Docking(nanome.PluginInstance): def __init__(self): - self._menu = DockingMenu(self) + self._menu = None self._calculations = None self._autobox = True @@ -23,10 +25,10 @@ def start(self): # Function called when user clicks on the "Run" button in Nanome def on_run(self): menu = self._menu - if menu._selected_receptor == None or menu._selected_site == None or menu._selected_ligands == []: + if menu.is_ready_for_docking(): self.open_menu() else: - self.run_docking(menu._selected_receptor[1], menu._selected_ligands, menu._selected_site[1]) + self.run_docking(menu.get_receptor(), menu.get_ligands(), menu.get_site(), menu.get_params()) def on_advanced_settings(self): nanome.util.Logs.debug("Advanced Settings") @@ -50,7 +52,7 @@ def make_plugin_usable(self): def on_complex_list_received(self, complexes): self._menu.change_complex_list(complexes) - def run_docking(self, receptor, ligand_list, site): + def run_docking(self, receptor, ligands, site, params): has_site = site != None def on_complexes_received(complexes): @@ -68,7 +70,7 @@ def on_complexes_received(complexes): Docking.convert_atoms_to_absolute_position(ligand) for molecule in ligand.molecules: ligands.add_molecule(molecule) - self._calculations.start_docking(receptor, ligands, site, self._menu._exhaustiveness, self._menu._modes, self._menu._align, self._menu._replace, self._menu._scoring_only, self._menu._autobox_size) + self._calculations.start_docking(receptor, ligands, site, params) if self._menu._run_button.unusable == True: return @@ -77,7 +79,7 @@ def on_complexes_received(complexes): request_list = [receptor.index] if has_site: request_list.append(site.index) - request_list += [x.index for x in ligand_list] + request_list += [x.index for x in ligands] self.request_complexes(request_list, on_complexes_received) @staticmethod @@ -109,14 +111,22 @@ class SminaDocking(Docking): def __init__(self): super(SminaDocking, self).__init__() self._calculations = Smina(self) + self._menu = DockingMenu(self) class Autodock4Docking(Docking): def __init__(self): super(Autodock4Docking, self).__init__() self._calculations = Autodock4(self) + self._menu = DockingMenu(self) self._autobox = False +class RhodiumDocking(Docking): + def __init__(self): + super(RhodiumDocking, self).__init__() + self._calculations = Rhodium(self) + self._menu = DockingMenuRhodium(self) + def main(): name = None @@ -128,8 +138,11 @@ def main(): elif arg == "autodock4": name = "Autodock 4" cl = Autodock4Docking + elif arg == "rhodium": + name = "Rhodium" + cl = RhodiumDocking if name == None: - nanome.util.Logs.error("Please pass the docking software to use as an argument: smina|autodock4") + nanome.util.Logs.error("Please pass the docking software to use as an argument: smina|autodock4|rhodium") sys.exit(1) # Create the plugin, register Docking as the class to instantiate, and start listening diff --git a/nanome_docking/_DockingCalculationsRhodium.py b/nanome_docking/_DockingCalculationsRhodium.py new file mode 100644 index 0000000..ce19907 --- /dev/null +++ b/nanome_docking/_DockingCalculationsRhodium.py @@ -0,0 +1,123 @@ +import nanome +from nanome.util import Logs, Process +from nanome.util.enums import NotificationTypes + +import os +import tempfile +import traceback +import subprocess +from timeit import default_timer as timer + +RHODIUM_PATH = os.path.join(os.path.dirname(__file__), 'Rh_x64.exe') + +class DockingCalculations(): + def __init__(self, plugin): + self._plugin = plugin + + def start_docking(self, receptor, ligands, site, params): + self.initialize() + + receptor.io.to_pdb(self._protein_input.name) + nanome.util.Logs.debug("Saved PDB", self._protein_input.name) + ligands.io.to_sdf(self._ligands_input.name) + nanome.util.Logs.debug("Saved SDF", self._ligands_input.name) + + self._receptor = receptor + self._params = params + + # Start docking process + self._start_docking() + + def initialize(self): + self._protein_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb") + self._ligands_input = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf") + self._docking_output = tempfile.NamedTemporaryFile() + self._docking_output.close() + + def clean_files(self, docking_result): + os.remove(self._protein_input.name) + os.remove(self._ligands_input.name) + os.remove(self._docking_output.name + ".csv") + for entry in docking_result: + os.remove(entry[0]) + pass + + def update(self): + return + + def _start_docking(self): + self.__proc = Process() + self.__proc.executable_path = RHODIUM_PATH + self.__proc.args = [self._protein_input.name, self._ligands_input.name, + '--outfile', self._docking_output.name, + '--refine', str(self._params['poses']), + '--resolution', str(self._params['grid_resolution']), + '--refine', str(self._params['poses']), + '--nr', str(self._params['rotamers'])] + self.__proc.output_text = True + + if self._params['ignore_hetatoms']: + args += ['--ignore_pdb_hetatm'] + + nanome.util.Logs.debug("Run Rhodium") + self._start_timer = timer() + try: + self.__proc.on_error = self._docking_error + self.__proc.on_done = self._docking_finished + self.__proc.start() + except: + nanome.util.Logs.error("Couldn't execute Rhodium, please check if executable is in the plugin folder and has permissions. Path:", exe_path, traceback.format_exc()) + self._plugin.make_plugin_usable() + self._plugin.send_notification(NotificationTypes.error, "Docking error, check plugin") + return + + self._plugin.send_notification(NotificationTypes.message, "Docking started") + + def _docking_error(self, error): + Logs.error("Docking error:", error) + + def read_csv(self): + result = [] + with open(self._docking_output.name + ".csv", 'r') as file: + lines = file.readlines() + for line in lines: + if line.startswith('seed') == False: + continue + line_split = line.split(',') + result.append([line_split[5].strip(), + line_split[13].strip(), + line_split[41].strip(), + line_split[43].strip()]) + return result + + def assemble_result(self, docking_output): + docked_ligands = nanome.api.structure.Complex() + for entry in docking_output: + complex = nanome.structure.Complex.io.from_sdf(path=entry[0]) + docked_ligands.add_molecule(complex.molecules[0]) + + def bonds_added(complex_arr): + docked_ligands_bonded = complex_arr[0] + docked_ligands_bonded.molecular.name = "Docking" + docked_ligands_bonded.rendering.visible = True + if self._params['align'] == True: + docked_ligands_bonded.transform.position = self._receptor.transform.position + docked_ligands_bonded.transform.rotation = self._receptor.transform.rotation + docked_ligands_bonded.rendering.boxed = True + + nanome.util.Logs.debug("Update workspace") + self._plugin.add_result_to_workspace([docked_ligands_bonded]) + + self._plugin.add_bonds([docked_ligands], bonds_added) + + + def _docking_finished(self, return_value): + end = timer() + nanome.util.Logs.debug("Docking Finished in", end - self._start_timer, "seconds") + + docking_output = self.read_csv() + self.assemble_result(docking_output) + + self.clean_files(docking_output) + self._plugin.make_plugin_usable() + self._plugin.send_notification(NotificationTypes.success, "Docking finished") diff --git a/nanome_docking/_DockingMenuRhodium.py b/nanome_docking/_DockingMenuRhodium.py new file mode 100644 index 0000000..fcabfb6 --- /dev/null +++ b/nanome_docking/_DockingMenuRhodium.py @@ -0,0 +1,225 @@ +import nanome +from nanome.api.ui.image import Image as Image + +import os + +class DockingMenuRhodium(): + def __init__(self, docking_plugin): + self._plugin = docking_plugin + self._selected_receptor = None + self._selected_ligands = [] + self._grid_resolution = 1.4 + self._poses = 96 + self._rotamer = 3 + self._run_button = None + self._align = True + self._ignore_hetatoms = False + self._tab = None + + def is_ready_for_docking(self): + return self._selected_receptor != None and len(self._selected_ligands) > 0 + + def get_receptor(self): + return self._selected_receptor.complex + + def get_ligands(self): + ligands = [] + for item in self._selected_ligands: + ligands.append(item.complex) + return ligands + + def get_site(self): + return None + + def get_params(self): + return { "receptor":self._selected_receptor, + "ligands":self._selected_ligands, + "grid_resolution":self._grid_resolution, + "poses":self._poses, + "rotamers":self._rotamer, + "align":self._align, + "ignore_hetatoms":self._ignore_hetatoms + } + + def _run_docking(self): + if self._selected_receptor == None or len(self._selected_ligands) == 0: + nanome.util.Logs.warning("Trying to run docking without having one receptor, and at least one ligand selected") + self._plugin.send_notification(NotificationTypes.error, "Please select a receptor, and at least one ligand") + return + ligands = [] + for item in self._selected_ligands: + ligands.append(item.complex) + self._plugin.run_docking(self.get_receptor(), self.get_ligands(), self.get_site(), self.get_params()) + + def make_plugin_usable(self, state=True): + self._run_button.unusable = not state + self._plugin.update_content(self._run_button) + + def receptor_pressed(self, button): + lastSelected = self._selected_receptor + if lastSelected != None: + lastSelected.selected = False + self._plugin.update_content(lastSelected) + button.selected = True + self._selected_receptor = button + self._plugin.update_content(button) + self._receptor_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'checkmark.png') + self._plugin.update_content(self._receptor_checkmark) + + def ligand_pressed(self, button): + if button.selected == False: + button.selected = True + self._selected_ligands.append(button) + else: + button.selected = False + self._selected_ligands.remove(button) + self._plugin.update_content(button) + if len(self._selected_ligands) != 0: + self._ligand_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'checkmark.png') + else: + self._ligand_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'none.png') + self._plugin.update_content(self._ligand_checkmark) + + def change_complex_list(self, complex_list): + def complex_pressed(button): + if self._tab.text.value_idle == "Receptor": + self.receptor_pressed(button) + elif self._tab.text.value_idle == "Ligand": + self.ligand_pressed(button) + + self._selected_receptor = None + self._selected_ligands = [] + self._complex_list.items = [] + self._receptor_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'none.png') + self._ligand_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'none.png') + + for complex in complex_list: + clone = self._complex_item_prefab.clone() + ln_btn = clone.get_children()[0] + btn = ln_btn.get_content() + btn.set_all_text(complex.molecular.name) + btn.complex = complex + btn.register_pressed_callback(complex_pressed) + self._complex_list.items.append(clone) + + self._plugin.update_menu(self._menu) + + def build_menu(self): + # defining callbacks + def run_button_pressed_callback(button): + self._run_docking() + + def grid_resolution_changed(input): + try: + self._grid_resolution = float(input.input_text) + nanome.util.Logs.debug("Grid resolution set to", self._grid_resolution) + except: + self._grid_resolution = 1.4 + + def poses_changed(input): + try: + self._poses = int(input.input_text) + nanome.util.Logs.debug("Poses count set to", self._poses) + except: + self._poses = 96 + if self._poses <= 0: + self._poses = 96 + + def rotamer_changed(input): + try: + self._rotamer = int(input.input_text) + nanome.util.Logs.debug("Rotamer count set to", self._rotamer) + except: + self._rotamer = 3 + if self._rotamer <= 0: + self._rotamer = 3 + + def tab_button_pressed_callback(button): + if self._tab == button: + return + + self._tab.selected = False + button.selected = True + self._tab = button + + if button.text.value_idle == "Receptor": + for item in self._complex_list.items: + btn = item.get_children()[0].get_content() + if btn == self._selected_receptor: + btn.selected = True + else: + btn.selected = False + elif button.text.value_idle == "Ligand": + for item in self._complex_list.items: + btn = item.get_children()[0].get_content() + if btn in self._selected_ligands: + btn.selected = True + else: + btn.selected = False + + self._plugin.update_menu(self._menu) + + def align_button_pressed_callback(button): + self._align = not self._align + button.selected = self._align + self._plugin.update_content(button) + + def ignore_hetatoms_pressed_callback(button): + self._ignore_hetatoms = not self._ignore_hetatoms + button.selected = self._ignore_hetatoms + self._plugin.update_content(button) + + # Create a prefab that will be used to populate the lists + self._complex_item_prefab = nanome.ui.LayoutNode() + self._complex_item_prefab.layout_orientation = nanome.ui.LayoutNode.LayoutTypes.horizontal + child = self._complex_item_prefab.create_child_node() + child.forward_dist = 0.002 + child.add_new_button() + + # loading menus + menu = nanome.ui.Menu.io.from_json(os.path.join(os.path.dirname(__file__), '_docking_menu_rhodium.json')) + self._plugin.menu = menu + + # images + none_path = os.path.join(os.path.dirname(__file__), 'none.png') + self._receptor_checkmark = menu.root.find_node("ReceptorIcon", True).add_new_image(none_path) + self._receptor_checkmark.scaling_option = Image.ScalingOptions.fit + self._ligand_checkmark = menu.root.find_node("LigandIcon", True).add_new_image(none_path) + self._ligand_checkmark.scaling_option = Image.ScalingOptions.fit + + # texts + txt1 = menu.root.find_node("GridResolutionInput", True).get_content() + txt1.register_changed_callback(grid_resolution_changed) + + txt2 = menu.root.find_node("PosesCountInput", True).get_content() + txt2.register_changed_callback(poses_changed) + + txt3 = menu.root.find_node("RotamerCountInput", True).get_content() + txt3.register_changed_callback(rotamer_changed) + + # buttons + receptor_btn = menu.root.find_node("ReceptorButton", True).get_content() + receptor_btn.register_pressed_callback(tab_button_pressed_callback) + receptor_btn.selected = True + self._tab = receptor_btn + + ligand_btn = menu.root.find_node("LigandButton", True).get_content() + ligand_btn.register_pressed_callback(tab_button_pressed_callback) + + align_btn = menu.root.find_node("AlignButton", True).get_content() + align_btn.register_pressed_callback(align_button_pressed_callback) + align_btn.selected = True + + run_button = menu.root.find_node("RunButton", True).get_content() + run_button.register_pressed_callback(run_button_pressed_callback) + self._run_button = run_button + + # lists + self._complex_list = menu.root.find_node("ComplexList", True).get_content() + self._receptor_tab = menu.root.find_node("ReceptorButton", True).get_content() + self._ligand_tab = menu.root.find_node("LigandButton", True).get_content() + + # Update the menu + self._menu = menu + self._plugin.update_menu(menu) + nanome.util.Logs.debug("Constructed plugin menu") diff --git a/nanome_docking/_docking_menu_rhodium.json b/nanome_docking/_docking_menu_rhodium.json new file mode 100644 index 0000000..f42fe48 --- /dev/null +++ b/nanome_docking/_docking_menu_rhodium.json @@ -0,0 +1 @@ +{"title": "Docking", "version": 0, "width": 0.829999983310699, "height": 0.600000023841858, "is_menu": true, "effective_root": {"name": "Root", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 1, "forward_dist": 0, "padding_type": 1, "padding_x": -1, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "", "text_vertical_align": 1, "text_horizontal_align": 1, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": [{"name": "LeftSide", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Top", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 2, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "RecepeterData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "ReceptorIcon", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "ReceptorText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Receptor:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}, {"name": "LigandData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "LigandIcon", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "LigandText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Ligand:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}]}, {"name": "Bot", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 4, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Tabs", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.270000010728836, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Receptor", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "ReceptorButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Receptor", "text_value_selected": "Receptor", "text_value_highlighted": "Receptor", "text_value_selected_highlighted": "Receptor", "text_value_unusable": "Receptor", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.280000001192093, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Ligand", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "LigandButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Ligand", "text_value_selected": "Ligand", "text_value_highlighted": "Ligand", "text_value_selected_highlighted": "Ligand", "text_value_unusable": "Ligand", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}]}, {"name": "List", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0.00999999977648258, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Mesh", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"mesh_color": 691685119, "type_name": "Mesh"}, "children": []}, {"name": "ComplexList", "enabled": true, "layer": 1, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0.00999999977648258, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"display_columns": 1, "display_rows": 3, "total_columns": 1, "unusable": false, "type_name": "List"}, "children": []}]}]}]}, {"name": "RightSide", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.75, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "GridResolution", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Grid Res.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "GridResolutionInput", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 5, "placeholder_text": "1.4", "input_text": "10", "type_name": "Text Input"}, "children": []}]}, {"name": "PosesCount", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Poses ct.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "PosesCountInput", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 3, "placeholder_text": "96", "input_text": "5", "type_name": "Text Input"}, "children": []}]}, {"name": "RotamerCount", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Rotamer ct.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "RotamerCountInput", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 2, "placeholder_text": "3", "input_text": "4", "type_name": "Text Input"}, "children": []}]}, {"name": "AlignAfter", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Align After", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "AlignButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "off", "text_value_selected": "on", "text_value_highlighted": "off", "text_value_selected_highlighted": "on", "text_value_unusable": "off", "text_auto_size": true, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "IgnoreHet", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Ignore Het.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.330000013113022, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "IgnoreHetButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "off", "text_value_selected": "on", "text_value_highlighted": "off", "text_value_selected_highlighted": "on", "text_value_unusable": "off", "text_auto_size": true, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Run", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "RunButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Run", "text_value_selected": "Run", "text_value_highlighted": "Run", "text_value_selected_highlighted": "Run", "text_value_unusable": "Running...", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.430000007152557, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}]}]}} \ No newline at end of file From ff2cc9cadd34eefc78ef2a67d5f570b28411a6e5 Mon Sep 17 00:00:00 2001 From: Ramji Date: Wed, 11 Sep 2019 11:34:51 -0700 Subject: [PATCH 02/19] Fix menu text inputs. Fix inputs --- nanome_docking/_DockingCalculationsRhodium.py | 78 ++++++++++++++----- nanome_docking/_docking_menu_rhodium.json | 2 +- 2 files changed, 61 insertions(+), 19 deletions(-) diff --git a/nanome_docking/_DockingCalculationsRhodium.py b/nanome_docking/_DockingCalculationsRhodium.py index ce19907..26a7c56 100644 --- a/nanome_docking/_DockingCalculationsRhodium.py +++ b/nanome_docking/_DockingCalculationsRhodium.py @@ -16,45 +16,85 @@ def __init__(self, plugin): def start_docking(self, receptor, ligands, site, params): self.initialize() - - receptor.io.to_pdb(self._protein_input.name) - nanome.util.Logs.debug("Saved PDB", self._protein_input.name) - ligands.io.to_sdf(self._ligands_input.name) - nanome.util.Logs.debug("Saved SDF", self._ligands_input.name) - + self._ligands = ligands self._receptor = receptor self._params = params + self.prepare_receptor(receptor) - # Start docking process - self._start_docking() + def update(self): + return def initialize(self): self._protein_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb") + self._protein_converted_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb") self._ligands_input = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf") + self._ligands_converted_input = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf") self._docking_output = tempfile.NamedTemporaryFile() self._docking_output.close() def clean_files(self, docking_result): + self._protein_input.close() + self._protein_converted_input.close() + self._ligands_input.close() + self._ligands_converted_input.close() os.remove(self._protein_input.name) + os.remove(self._protein_converted_input.name) os.remove(self._ligands_input.name) + os.remove(self._ligands_converted_input.name) os.remove(self._docking_output.name + ".csv") for entry in docking_result: os.remove(entry[0]) pass - def update(self): - return + def prepare_receptor(self, receptor): + residues_to_remove = [] + for residue in receptor.residues: + if residue.name == "HOH": + residues_to_remove.append(residue) + + for residue in residues_to_remove: + residue.parent.remove_residue(residue) + + receptor.io.to_pdb(self._protein_input.name) + + proc = Process() + proc.executable_path = 'obabel' + proc.args = ['-ipdb', self._protein_input.name, + '-opdb', '-O' + self._protein_converted_input.name, '-h'] + proc.on_done = self.receptor_ready + proc.start() + + def receptor_ready(self, return_value): + self._ligands.io.to_sdf(self._ligands_input.name) + self._start_conversion() + + def _start_conversion(self): + proc = Process() + proc.executable_path = 'obabel' + proc.args = ['-isdf', self._ligands_input.name, + '-osdf', '-O' + self._ligands_converted_input.name] + proc.on_done = self._conversion_finished + proc.start() + + def _conversion_finished(self, return_value): + self._start_docking() def _start_docking(self): - self.__proc = Process() - self.__proc.executable_path = RHODIUM_PATH - self.__proc.args = [self._protein_input.name, self._ligands_input.name, + proc = Process() + proc.executable_path = RHODIUM_PATH + proc.args = [self._protein_converted_input.name, self._ligands_converted_input.name, '--outfile', self._docking_output.name, '--refine', str(self._params['poses']), '--resolution', str(self._params['grid_resolution']), '--refine', str(self._params['poses']), '--nr', str(self._params['rotamers'])] - self.__proc.output_text = True + proc.output_text = True + proc.on_output = self._on_docking_output + proc.on_error = self._on_docking_error + proc.on_done = self._docking_finished + proc.cwd_path = os.path.dirname(__file__) + + Logs.debug("Start docking:", proc.args) if self._params['ignore_hetatoms']: args += ['--ignore_pdb_hetatm'] @@ -62,9 +102,7 @@ def _start_docking(self): nanome.util.Logs.debug("Run Rhodium") self._start_timer = timer() try: - self.__proc.on_error = self._docking_error - self.__proc.on_done = self._docking_finished - self.__proc.start() + proc.start() except: nanome.util.Logs.error("Couldn't execute Rhodium, please check if executable is in the plugin folder and has permissions. Path:", exe_path, traceback.format_exc()) self._plugin.make_plugin_usable() @@ -73,7 +111,11 @@ def _start_docking(self): self._plugin.send_notification(NotificationTypes.message, "Docking started") - def _docking_error(self, error): + def _on_docking_output(self, output): + Logs.debug("Docking output:", output) + pass + + def _on_docking_error(self, error): Logs.error("Docking error:", error) def read_csv(self): diff --git a/nanome_docking/_docking_menu_rhodium.json b/nanome_docking/_docking_menu_rhodium.json index f42fe48..38cefc4 100644 --- a/nanome_docking/_docking_menu_rhodium.json +++ b/nanome_docking/_docking_menu_rhodium.json @@ -1 +1 @@ -{"title": "Docking", "version": 0, "width": 0.829999983310699, "height": 0.600000023841858, "is_menu": true, "effective_root": {"name": "Root", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 1, "forward_dist": 0, "padding_type": 1, "padding_x": -1, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "", "text_vertical_align": 1, "text_horizontal_align": 1, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": [{"name": "LeftSide", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Top", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 2, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "RecepeterData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "ReceptorIcon", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "ReceptorText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Receptor:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}, {"name": "LigandData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "LigandIcon", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "LigandText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Ligand:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}]}, {"name": "Bot", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 4, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Tabs", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.270000010728836, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Receptor", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "ReceptorButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Receptor", "text_value_selected": "Receptor", "text_value_highlighted": "Receptor", "text_value_selected_highlighted": "Receptor", "text_value_unusable": "Receptor", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.280000001192093, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Ligand", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "LigandButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Ligand", "text_value_selected": "Ligand", "text_value_highlighted": "Ligand", "text_value_selected_highlighted": "Ligand", "text_value_unusable": "Ligand", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}]}, {"name": "List", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0.00999999977648258, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Mesh", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"mesh_color": 691685119, "type_name": "Mesh"}, "children": []}, {"name": "ComplexList", "enabled": true, "layer": 1, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0.00999999977648258, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"display_columns": 1, "display_rows": 3, "total_columns": 1, "unusable": false, "type_name": "List"}, "children": []}]}]}]}, {"name": "RightSide", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.75, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "GridResolution", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Grid Res.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "GridResolutionInput", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 5, "placeholder_text": "1.4", "input_text": "10", "type_name": "Text Input"}, "children": []}]}, {"name": "PosesCount", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Poses ct.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "PosesCountInput", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 3, "placeholder_text": "96", "input_text": "5", "type_name": "Text Input"}, "children": []}]}, {"name": "RotamerCount", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Rotamer ct.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "RotamerCountInput", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 2, "placeholder_text": "3", "input_text": "4", "type_name": "Text Input"}, "children": []}]}, {"name": "AlignAfter", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Align After", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "AlignButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "off", "text_value_selected": "on", "text_value_highlighted": "off", "text_value_selected_highlighted": "on", "text_value_unusable": "off", "text_auto_size": true, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "IgnoreHet", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Ignore Het.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.330000013113022, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "IgnoreHetButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "off", "text_value_selected": "on", "text_value_highlighted": "off", "text_value_selected_highlighted": "on", "text_value_unusable": "off", "text_auto_size": true, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Run", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "RunButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Run", "text_value_selected": "Run", "text_value_highlighted": "Run", "text_value_selected_highlighted": "Run", "text_value_unusable": "Running...", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.430000007152557, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}]}]}} \ No newline at end of file +{"title": "Docking", "version": 0, "width": 0.829999983310699, "height": 0.600000023841858, "is_menu": true, "effective_root": {"name": "Root", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 1, "forward_dist": 0, "padding_type": 1, "padding_x": -1, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "", "text_vertical_align": 1, "text_horizontal_align": 1, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": [{"name": "LeftSide", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Top", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 2, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "RecepeterData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "ReceptorIcon", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "ReceptorText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Receptor:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}, {"name": "LigandData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "LigandIcon", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "LigandText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Ligand:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}]}, {"name": "Bot", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 4, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Tabs", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.270000010728836, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Receptor", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "ReceptorButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Receptor", "text_value_selected": "Receptor", "text_value_highlighted": "Receptor", "text_value_selected_highlighted": "Receptor", "text_value_unusable": "Receptor", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.280000001192093, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Ligand", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "LigandButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Ligand", "text_value_selected": "Ligand", "text_value_highlighted": "Ligand", "text_value_selected_highlighted": "Ligand", "text_value_unusable": "Ligand", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}]}, {"name": "List", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0.00999999977648258, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Mesh", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"mesh_color": 691685119, "type_name": "Mesh"}, "children": []}, {"name": "ComplexList", "enabled": true, "layer": 1, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0.00999999977648258, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"display_columns": 1, "display_rows": 3, "total_columns": 1, "unusable": false, "type_name": "List"}, "children": []}]}]}]}, {"name": "RightSide", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.75, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "GridResolution", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Grid Res.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "GridResolutionInput", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 5, "placeholder_text": "1.4", "input_text": "1.4", "type_name": "Text Input"}, "children": []}]}, {"name": "PosesCount", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Poses ct.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "PosesCountInput", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 3, "placeholder_text": "96", "input_text": "96", "type_name": "Text Input"}, "children": []}]}, {"name": "RotamerCount", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Rotamer ct.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "RotamerCountInput", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 2, "placeholder_text": "3", "input_text": "3", "type_name": "Text Input"}, "children": []}]}, {"name": "AlignAfter", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Align After", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "AlignButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "off", "text_value_selected": "on", "text_value_highlighted": "off", "text_value_selected_highlighted": "on", "text_value_unusable": "off", "text_auto_size": true, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "IgnoreHet", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Ignore Het.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.330000013113022, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "IgnoreHetButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "off", "text_value_selected": "on", "text_value_highlighted": "off", "text_value_selected_highlighted": "on", "text_value_unusable": "off", "text_auto_size": true, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Run", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "RunButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Run", "text_value_selected": "Run", "text_value_highlighted": "Run", "text_value_selected_highlighted": "Run", "text_value_unusable": "Running...", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.430000007152557, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}]}]}} \ No newline at end of file From 1ff66dd386bf4984ad14c3ca34579b4852f760df Mon Sep 17 00:00:00 2001 From: Ramji Date: Thu, 12 Sep 2019 09:44:52 -0700 Subject: [PATCH 03/19] Fix Rhodium process execution --- nanome_docking/_DockingCalculationsRhodium.py | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/nanome_docking/_DockingCalculationsRhodium.py b/nanome_docking/_DockingCalculationsRhodium.py index 26a7c56..75375c9 100644 --- a/nanome_docking/_DockingCalculationsRhodium.py +++ b/nanome_docking/_DockingCalculationsRhodium.py @@ -13,6 +13,7 @@ class DockingCalculations(): def __init__(self, plugin): self._plugin = plugin + self.__docking_running = False def start_docking(self, receptor, ligands, site, params): self.initialize() @@ -22,7 +23,13 @@ def start_docking(self, receptor, ligands, site, params): self.prepare_receptor(receptor) def update(self): - return + if self.__docking_running == False: + return + + self.__process.communicate() + if self.__process.poll() != None: + self.__docking_running = False + self._docking_finished() def initialize(self): self._protein_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb") @@ -43,6 +50,7 @@ def clean_files(self, docking_result): os.remove(self._ligands_converted_input.name) os.remove(self._docking_output.name + ".csv") for entry in docking_result: + os.chmod(entry[0], 0o777) os.remove(entry[0]) pass @@ -80,29 +88,21 @@ def _conversion_finished(self, return_value): self._start_docking() def _start_docking(self): - proc = Process() - proc.executable_path = RHODIUM_PATH - proc.args = [self._protein_converted_input.name, self._ligands_converted_input.name, + args = [RHODIUM_PATH, self._protein_converted_input.name, self._ligands_converted_input.name, '--outfile', self._docking_output.name, '--refine', str(self._params['poses']), '--resolution', str(self._params['grid_resolution']), '--refine', str(self._params['poses']), '--nr', str(self._params['rotamers'])] - proc.output_text = True - proc.on_output = self._on_docking_output - proc.on_error = self._on_docking_error - proc.on_done = self._docking_finished - proc.cwd_path = os.path.dirname(__file__) - - Logs.debug("Start docking:", proc.args) if self._params['ignore_hetatoms']: args += ['--ignore_pdb_hetatm'] - nanome.util.Logs.debug("Run Rhodium") + Logs.debug("Start Rhodium:", args) + self._start_timer = timer() try: - proc.start() + self.__process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=os.path.dirname(__file__)) except: nanome.util.Logs.error("Couldn't execute Rhodium, please check if executable is in the plugin folder and has permissions. Path:", exe_path, traceback.format_exc()) self._plugin.make_plugin_usable() @@ -110,6 +110,7 @@ def _start_docking(self): return self._plugin.send_notification(NotificationTypes.message, "Docking started") + self.__docking_running = True def _on_docking_output(self, output): Logs.debug("Docking output:", output) @@ -135,8 +136,12 @@ def read_csv(self): def assemble_result(self, docking_output): docked_ligands = nanome.api.structure.Complex() for entry in docking_output: - complex = nanome.structure.Complex.io.from_sdf(path=entry[0]) - docked_ligands.add_molecule(complex.molecules[0]) + complex = nanome.structure.Complex.io.from_pdb(path=entry[0]) + molecule = next(complex.molecules) + molecule._associated['score'] = entry[1] + molecule._associated['affinity'] = entry[2] + molecule._associated['pose_population'] = entry[3] + docked_ligands.add_molecule(molecule) def bonds_added(complex_arr): docked_ligands_bonded = complex_arr[0] @@ -153,7 +158,7 @@ def bonds_added(complex_arr): self._plugin.add_bonds([docked_ligands], bonds_added) - def _docking_finished(self, return_value): + def _docking_finished(self): end = timer() nanome.util.Logs.debug("Docking Finished in", end - self._start_timer, "seconds") From 241186b4145f629bd40a46e3472674b410ded1a0 Mon Sep 17 00:00:00 2001 From: Ramji Date: Thu, 12 Sep 2019 15:13:34 -0700 Subject: [PATCH 04/19] Cleaning some more code --- nanome_docking/Docking.py | 26 +++++++----- nanome_docking/_DockingCalculationsRhodium.py | 40 +++++++++++++------ 2 files changed, 44 insertions(+), 22 deletions(-) diff --git a/nanome_docking/Docking.py b/nanome_docking/Docking.py index 9b22844..3208601 100644 --- a/nanome_docking/Docking.py +++ b/nanome_docking/Docking.py @@ -15,28 +15,34 @@ def __init__(self): self._calculations = None self._autobox = True - # Function called when Nanome connects to the Plugin, after its instantiation + # Called when Nanome connects to the Plugin, after its instantiation def start(self): self._menu.build_menu() if self._autobox == False: self._menu.disable_autobox() + # Request shallow complex (name, position, orientation), to display them in a list self.request_complex_list(self.on_complex_list_received) - # Function called when user clicks on the "Run" button in Nanome + # Called when user clicks on the "Run" button in Nanome def on_run(self): menu = self._menu - if menu.is_ready_for_docking(): + # If menu doesn't have Receptor and Ligands selected, open it + # Else, just start docking + if menu.is_ready_for_docking() == False: self.open_menu() else: self.run_docking(menu.get_receptor(), menu.get_ligands(), menu.get_site(), menu.get_params()) + # Called when user click on the "Advanced Settings" button in Nanome def on_advanced_settings(self): nanome.util.Logs.debug("Advanced Settings") self.open_menu() + # Called when a complex is added to the workspace in Nanome def on_complex_added(self): self.request_complex_list(self.on_complex_list_received) + # Called when a complex is removed from the workspace in Nanome def on_complex_removed(self): self.request_complex_list(self.on_complex_list_received) @@ -48,14 +54,19 @@ def open_menu(self): def make_plugin_usable(self): self._menu.make_plugin_usable() - # Function called when Nanome returns the complex list after a request def on_complex_list_received(self, complexes): self._menu.change_complex_list(complexes) def run_docking(self, receptor, ligands, site, params): + # Change the plugin to be "unusable" + if self._menu._run_button.unusable == True: + return + self._menu.make_plugin_usable(False) + has_site = site != None def on_complexes_received(complexes): + # When deep complexes data are received, unpack them and prepare ligand for docking receptor = complexes[0] self._receptor = receptor Docking.convert_atoms_to_absolute_position(receptor) @@ -72,10 +83,7 @@ def on_complexes_received(complexes): ligands.add_molecule(molecule) self._calculations.start_docking(receptor, ligands, site, params) - if self._menu._run_button.unusable == True: - return - self._menu.make_plugin_usable(False) - + # Request complexes to Nanome in this order: [receptor, site (if any), ligand, ligand,...] request_list = [receptor.index] if has_site: request_list.append(site.index) @@ -94,7 +102,7 @@ def convert_atoms_to_relative_position(complex, reference): for atom in complex.atoms: atom.molecular.position = mat * atom.molecular.position - # Function called every update tick of the Plugin + # Called every update tick of the Plugin def update(self): self._calculations.update() diff --git a/nanome_docking/_DockingCalculationsRhodium.py b/nanome_docking/_DockingCalculationsRhodium.py index 75375c9..0f34e41 100644 --- a/nanome_docking/_DockingCalculationsRhodium.py +++ b/nanome_docking/_DockingCalculationsRhodium.py @@ -15,13 +15,20 @@ def __init__(self, plugin): self._plugin = plugin self.__docking_running = False + # Entry point, where everything starts def start_docking(self, receptor, ligands, site, params): + # Create temporary files self.initialize() + self._ligands = ligands self._receptor = receptor self._params = params + self.prepare_receptor(receptor) + # Docking process needs to be check manually in an update loop for now + # This is due to a current bug with the plugin system Process API with process outputting a lot of text + # In the future, no update loop will be needed to check when Rhodium has ended def update(self): if self.__docking_running == False: return @@ -55,6 +62,7 @@ def clean_files(self, docking_result): pass def prepare_receptor(self, receptor): + # Remove waters residues_to_remove = [] for residue in receptor.residues: if residue.name == "HOH": @@ -63,8 +71,10 @@ def prepare_receptor(self, receptor): for residue in residues_to_remove: residue.parent.remove_residue(residue) + # Write pdb file for openbabel receptor.io.to_pdb(self._protein_input.name) + # Use openbabel to add hydrogens proc = Process() proc.executable_path = 'obabel' proc.args = ['-ipdb', self._protein_input.name, @@ -72,11 +82,14 @@ def prepare_receptor(self, receptor): proc.on_done = self.receptor_ready proc.start() + # Callback when obabel is done def receptor_ready(self, return_value): self._ligands.io.to_sdf(self._ligands_input.name) self._start_conversion() def _start_conversion(self): + # Temporary solution to convert sdf V3000 to V2000 + # A V2000 writer will be added to the plugin system proc = Process() proc.executable_path = 'obabel' proc.args = ['-isdf', self._ligands_input.name, @@ -88,6 +101,7 @@ def _conversion_finished(self, return_value): self._start_docking() def _start_docking(self): + # Start process manually, because of problem described above Update function args = [RHODIUM_PATH, self._protein_converted_input.name, self._ligands_converted_input.name, '--outfile', self._docking_output.name, '--refine', str(self._params['poses']), @@ -104,7 +118,7 @@ def _start_docking(self): try: self.__process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=os.path.dirname(__file__)) except: - nanome.util.Logs.error("Couldn't execute Rhodium, please check if executable is in the plugin folder and has permissions. Path:", exe_path, traceback.format_exc()) + nanome.util.Logs.error("Couldn't execute Rhodium, please check if executable is in the plugin folder and has permissions. Path:", RHODIUM_PATH, traceback.format_exc()) self._plugin.make_plugin_usable() self._plugin.send_notification(NotificationTypes.error, "Docking error, check plugin") return @@ -112,13 +126,6 @@ def _start_docking(self): self._plugin.send_notification(NotificationTypes.message, "Docking started") self.__docking_running = True - def _on_docking_output(self, output): - Logs.debug("Docking output:", output) - pass - - def _on_docking_error(self, error): - Logs.error("Docking error:", error) - def read_csv(self): result = [] with open(self._docking_output.name + ".csv", 'r') as file: @@ -134,13 +141,18 @@ def read_csv(self): return result def assemble_result(self, docking_output): + # docking_output contains the lines from the csv file + docked_ligands = nanome.api.structure.Complex() for entry in docking_output: + # Read complex from pdb and extract molecule from it complex = nanome.structure.Complex.io.from_pdb(path=entry[0]) molecule = next(complex.molecules) + # Write docking information in the molecule molecule._associated['score'] = entry[1] molecule._associated['affinity'] = entry[2] molecule._associated['pose_population'] = entry[3] + # Add it to the result complex docked_ligands.add_molecule(molecule) def bonds_added(complex_arr): @@ -155,16 +167,18 @@ def bonds_added(complex_arr): nanome.util.Logs.debug("Update workspace") self._plugin.add_result_to_workspace([docked_ligands_bonded]) - self._plugin.add_bonds([docked_ligands], bonds_added) + # Docking process is over, clean files and make plugin available again + self.clean_files(docking_output) + self._plugin.make_plugin_usable() + self._plugin.send_notification(NotificationTypes.success, "Docking finished") + # Add bonds to the result complex + self._plugin.add_bonds([docked_ligands], bonds_added) def _docking_finished(self): end = timer() nanome.util.Logs.debug("Docking Finished in", end - self._start_timer, "seconds") + # When Rhodium finished, read csv, then assemble result ligands docking_output = self.read_csv() self.assemble_result(docking_output) - - self.clean_files(docking_output) - self._plugin.make_plugin_usable() - self._plugin.send_notification(NotificationTypes.success, "Docking finished") From e95bc5da90733cfa10642a214bafe75041108431 Mon Sep 17 00:00:00 2001 From: Ramji Date: Thu, 26 Sep 2019 15:00:46 -0700 Subject: [PATCH 05/19] Add logo and site selection. Remove conversion to V2000. Change default values --- nanome_docking/_DockingCalculationsRhodium.py | 27 ++++----- nanome_docking/_DockingMenuRhodium.py | 52 ++++++++++++++++-- nanome_docking/_docking_menu_rhodium.json | 2 +- nanome_docking/swri_logo.png | Bin 0 -> 177756 bytes 4 files changed, 58 insertions(+), 23 deletions(-) create mode 100644 nanome_docking/swri_logo.png diff --git a/nanome_docking/_DockingCalculationsRhodium.py b/nanome_docking/_DockingCalculationsRhodium.py index 0f34e41..48d7c94 100644 --- a/nanome_docking/_DockingCalculationsRhodium.py +++ b/nanome_docking/_DockingCalculationsRhodium.py @@ -22,6 +22,7 @@ def start_docking(self, receptor, ligands, site, params): self._ligands = ligands self._receptor = receptor + self._site = site self._params = params self.prepare_receptor(receptor) @@ -42,7 +43,7 @@ def initialize(self): self._protein_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb") self._protein_converted_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb") self._ligands_input = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf") - self._ligands_converted_input = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf") + self._site_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb") self._docking_output = tempfile.NamedTemporaryFile() self._docking_output.close() @@ -50,11 +51,11 @@ def clean_files(self, docking_result): self._protein_input.close() self._protein_converted_input.close() self._ligands_input.close() - self._ligands_converted_input.close() + self._site_input.close() os.remove(self._protein_input.name) os.remove(self._protein_converted_input.name) os.remove(self._ligands_input.name) - os.remove(self._ligands_converted_input.name) + os.remove(self._site_input.name) os.remove(self._docking_output.name + ".csv") for entry in docking_result: os.chmod(entry[0], 0o777) @@ -85,24 +86,13 @@ def prepare_receptor(self, receptor): # Callback when obabel is done def receptor_ready(self, return_value): self._ligands.io.to_sdf(self._ligands_input.name) - self._start_conversion() - - def _start_conversion(self): - # Temporary solution to convert sdf V3000 to V2000 - # A V2000 writer will be added to the plugin system - proc = Process() - proc.executable_path = 'obabel' - proc.args = ['-isdf', self._ligands_input.name, - '-osdf', '-O' + self._ligands_converted_input.name] - proc.on_done = self._conversion_finished - proc.start() - - def _conversion_finished(self, return_value): + if self._site != None: + self._site.io.to_sdf(self._site_input.name) self._start_docking() def _start_docking(self): # Start process manually, because of problem described above Update function - args = [RHODIUM_PATH, self._protein_converted_input.name, self._ligands_converted_input.name, + args = [RHODIUM_PATH, self._protein_converted_input.name, self._ligands_input.name, '--outfile', self._docking_output.name, '--refine', str(self._params['poses']), '--resolution', str(self._params['grid_resolution']), @@ -112,6 +102,9 @@ def _start_docking(self): if self._params['ignore_hetatoms']: args += ['--ignore_pdb_hetatm'] + if self._site != None: + args += ['--usegrid', self._site_input.name] + Logs.debug("Start Rhodium:", args) self._start_timer = timer() diff --git a/nanome_docking/_DockingMenuRhodium.py b/nanome_docking/_DockingMenuRhodium.py index fcabfb6..ebd1d54 100644 --- a/nanome_docking/_DockingMenuRhodium.py +++ b/nanome_docking/_DockingMenuRhodium.py @@ -8,9 +8,10 @@ def __init__(self, docking_plugin): self._plugin = docking_plugin self._selected_receptor = None self._selected_ligands = [] - self._grid_resolution = 1.4 - self._poses = 96 - self._rotamer = 3 + self._selected_site = None + self._grid_resolution = 2.5 + self._poses = 128 + self._rotamer = 6 self._run_button = None self._align = True self._ignore_hetatoms = False @@ -29,11 +30,14 @@ def get_ligands(self): return ligands def get_site(self): - return None + if self._selected_site == None: + return None + return self._selected_site.complex def get_params(self): return { "receptor":self._selected_receptor, "ligands":self._selected_ligands, + "site":self._selected_site, "grid_resolution":self._grid_resolution, "poses":self._poses, "rotamers":self._rotamer, @@ -44,7 +48,7 @@ def get_params(self): def _run_docking(self): if self._selected_receptor == None or len(self._selected_ligands) == 0: nanome.util.Logs.warning("Trying to run docking without having one receptor, and at least one ligand selected") - self._plugin.send_notification(NotificationTypes.error, "Please select a receptor, and at least one ligand") + self._plugin.send_notification(nanome.util.enums.NotificationTypes.error, "Please select a receptor, and at least one ligand") return ligands = [] for item in self._selected_ligands: @@ -80,18 +84,40 @@ def ligand_pressed(self, button): self._ligand_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'none.png') self._plugin.update_content(self._ligand_checkmark) + def site_pressed(self, button): + lastSelected = self._selected_site + if lastSelected == button: + button.selected = False + self._plugin.update_content(button) + self._selected_site = None + self._site_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'none.png') + self._plugin.update_content(self._site_checkmark) + return + elif lastSelected != None: + lastSelected.selected = False + self._plugin.update_content(lastSelected) + button.selected = True + self._selected_site = button + self._plugin.update_content(button) + self._site_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'checkmark.png') + self._plugin.update_content(self._site_checkmark) + def change_complex_list(self, complex_list): def complex_pressed(button): if self._tab.text.value_idle == "Receptor": self.receptor_pressed(button) elif self._tab.text.value_idle == "Ligand": self.ligand_pressed(button) + elif self._tab.text.value_idle == "Site": + self.site_pressed(button) self._selected_receptor = None self._selected_ligands = [] + self._selected_site = None self._complex_list.items = [] self._receptor_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'none.png') self._ligand_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'none.png') + self._site_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'none.png') for complex in complex_list: clone = self._complex_item_prefab.clone() @@ -156,6 +182,13 @@ def tab_button_pressed_callback(button): btn.selected = True else: btn.selected = False + elif button.text.value_idle == "Site": + for item in self._complex_list.items: + btn = item.get_children()[0].get_content() + if btn == self._selected_site: + btn.selected = True + else: + btn.selected = False self._plugin.update_menu(self._menu) @@ -182,10 +215,15 @@ def ignore_hetatoms_pressed_callback(button): # images none_path = os.path.join(os.path.dirname(__file__), 'none.png') + logo_path = os.path.join(os.path.dirname(__file__), 'swri_logo.png') self._receptor_checkmark = menu.root.find_node("ReceptorIcon", True).add_new_image(none_path) self._receptor_checkmark.scaling_option = Image.ScalingOptions.fit self._ligand_checkmark = menu.root.find_node("LigandIcon", True).add_new_image(none_path) self._ligand_checkmark.scaling_option = Image.ScalingOptions.fit + self._site_checkmark = menu.root.find_node("SiteIcon", True).add_new_image(none_path) + self._site_checkmark.scaling_option = Image.ScalingOptions.fit + logo_image = menu.root.find_node("LogoImage", True).add_new_image(logo_path) + logo_image.scaling_option = Image.ScalingOptions.fit # texts txt1 = menu.root.find_node("GridResolutionInput", True).get_content() @@ -206,6 +244,9 @@ def ignore_hetatoms_pressed_callback(button): ligand_btn = menu.root.find_node("LigandButton", True).get_content() ligand_btn.register_pressed_callback(tab_button_pressed_callback) + site_btn = menu.root.find_node("SiteButton", True).get_content() + site_btn.register_pressed_callback(tab_button_pressed_callback) + align_btn = menu.root.find_node("AlignButton", True).get_content() align_btn.register_pressed_callback(align_button_pressed_callback) align_btn.selected = True @@ -218,6 +259,7 @@ def ignore_hetatoms_pressed_callback(button): self._complex_list = menu.root.find_node("ComplexList", True).get_content() self._receptor_tab = menu.root.find_node("ReceptorButton", True).get_content() self._ligand_tab = menu.root.find_node("LigandButton", True).get_content() + self._site_tab = menu.root.find_node("SiteButton", True).get_content() # Update the menu self._menu = menu diff --git a/nanome_docking/_docking_menu_rhodium.json b/nanome_docking/_docking_menu_rhodium.json index 38cefc4..0851c8b 100644 --- a/nanome_docking/_docking_menu_rhodium.json +++ b/nanome_docking/_docking_menu_rhodium.json @@ -1 +1 @@ -{"title": "Docking", "version": 0, "width": 0.829999983310699, "height": 0.600000023841858, "is_menu": true, "effective_root": {"name": "Root", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 1, "forward_dist": 0, "padding_type": 1, "padding_x": -1, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "", "text_vertical_align": 1, "text_horizontal_align": 1, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": [{"name": "LeftSide", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Top", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 2, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "RecepeterData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "ReceptorIcon", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "ReceptorText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Receptor:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}, {"name": "LigandData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "LigandIcon", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "LigandText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Ligand:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}]}, {"name": "Bot", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 4, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Tabs", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.270000010728836, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Receptor", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "ReceptorButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Receptor", "text_value_selected": "Receptor", "text_value_highlighted": "Receptor", "text_value_selected_highlighted": "Receptor", "text_value_unusable": "Receptor", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.280000001192093, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Ligand", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "LigandButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Ligand", "text_value_selected": "Ligand", "text_value_highlighted": "Ligand", "text_value_selected_highlighted": "Ligand", "text_value_unusable": "Ligand", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}]}, {"name": "List", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0.00999999977648258, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Mesh", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"mesh_color": 691685119, "type_name": "Mesh"}, "children": []}, {"name": "ComplexList", "enabled": true, "layer": 1, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0.00999999977648258, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"display_columns": 1, "display_rows": 3, "total_columns": 1, "unusable": false, "type_name": "List"}, "children": []}]}]}]}, {"name": "RightSide", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.75, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "GridResolution", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Grid Res.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "GridResolutionInput", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 5, "placeholder_text": "1.4", "input_text": "1.4", "type_name": "Text Input"}, "children": []}]}, {"name": "PosesCount", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Poses ct.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "PosesCountInput", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 3, "placeholder_text": "96", "input_text": "96", "type_name": "Text Input"}, "children": []}]}, {"name": "RotamerCount", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Rotamer ct.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "RotamerCountInput", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 2, "placeholder_text": "3", "input_text": "3", "type_name": "Text Input"}, "children": []}]}, {"name": "AlignAfter", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Align After", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "AlignButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "off", "text_value_selected": "on", "text_value_highlighted": "off", "text_value_selected_highlighted": "on", "text_value_unusable": "off", "text_auto_size": true, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "IgnoreHet", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Ignore Het.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.330000013113022, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "IgnoreHetButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "off", "text_value_selected": "on", "text_value_highlighted": "off", "text_value_selected_highlighted": "on", "text_value_unusable": "off", "text_auto_size": true, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Run", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "RunButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Run", "text_value_selected": "Run", "text_value_highlighted": "Run", "text_value_selected_highlighted": "Run", "text_value_unusable": "Running...", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.430000007152557, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}]}]}} \ No newline at end of file +{"title": "Docking", "version": 0, "width": 0.829999983310699, "height": 0.600000023841858, "is_menu": true, "effective_root": {"name": "Root", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 1, "forward_dist": 0, "padding_type": 1, "padding_x": -1, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "", "text_vertical_align": 1, "text_horizontal_align": 1, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": [{"name": "LeftSide", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Top", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 2, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "RecepeterData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "ReceptorIcon", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "ReceptorText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Receptor:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}, {"name": "LigandData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "LigandIcon", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "LigandText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Ligand:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}, {"name": "SiteData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "SiteIcon", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "SiteText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Site:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}]}, {"name": "Bot", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 4, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Tabs", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.270000010728836, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Receptor", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "ReceptorButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Receptor", "text_value_selected": "Receptor", "text_value_highlighted": "Receptor", "text_value_selected_highlighted": "Receptor", "text_value_unusable": "Receptor", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.280000001192093, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Ligand", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "LigandButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Ligand", "text_value_selected": "Ligand", "text_value_highlighted": "Ligand", "text_value_selected_highlighted": "Ligand", "text_value_unusable": "Ligand", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Site", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "SiteButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Site", "text_value_selected": "Site", "text_value_highlighted": "Site", "text_value_selected_highlighted": "Site", "text_value_unusable": "Site", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}]}, {"name": "List", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0.00999999977648258, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Mesh", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"mesh_color": 691685119, "type_name": "Mesh"}, "children": []}, {"name": "ComplexList", "enabled": true, "layer": 1, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0.00999999977648258, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"display_columns": 1, "display_rows": 3, "total_columns": 1, "unusable": false, "type_name": "List"}, "children": []}]}]}]}, {"name": "RightSide", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.75, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "GridResolution", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Grid Res.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "GridResolutionInput", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 5, "placeholder_text": "2.5", "input_text": "2.5", "type_name": "Text Input"}, "children": []}]}, {"name": "PosesCount", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Poses ct.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "PosesCountInput", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 3, "placeholder_text": "128", "input_text": "128", "type_name": "Text Input"}, "children": []}]}, {"name": "RotamerCount", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Rotamer ct.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "RotamerCountInput", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 2, "placeholder_text": "6", "input_text": "6", "type_name": "Text Input"}, "children": []}]}, {"name": "AlignAfter", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Align After", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "AlignButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "off", "text_value_selected": "on", "text_value_highlighted": "off", "text_value_selected_highlighted": "on", "text_value_unusable": "off", "text_auto_size": true, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "IgnoreHet", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Ignore Het.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.330000013113022, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "IgnoreHetButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "off", "text_value_selected": "on", "text_value_highlighted": "off", "text_value_selected_highlighted": "on", "text_value_unusable": "off", "text_auto_size": true, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Run", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "RunButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Run", "text_value_selected": "Run", "text_value_highlighted": "Run", "text_value_selected_highlighted": "Run", "text_value_unusable": "Running...", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.430000007152557, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Logo", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1.5, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "LogoImage", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": []}]}]}]}} \ No newline at end of file diff --git a/nanome_docking/swri_logo.png b/nanome_docking/swri_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..4ecbbc1b359751635adf0cdec9896ce264746702 GIT binary patch literal 177756 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 z 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 L8`oD^F%td{ Date: Fri, 27 Sep 2019 13:47:40 -0700 Subject: [PATCH 06/19] Add padding around logo --- nanome_docking/_docking_menu_rhodium.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nanome_docking/_docking_menu_rhodium.json b/nanome_docking/_docking_menu_rhodium.json index 0851c8b..c837eb2 100644 --- a/nanome_docking/_docking_menu_rhodium.json +++ b/nanome_docking/_docking_menu_rhodium.json @@ -1 +1 @@ -{"title": "Docking", "version": 0, "width": 0.829999983310699, "height": 0.600000023841858, "is_menu": true, "effective_root": {"name": "Root", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 1, "forward_dist": 0, "padding_type": 1, "padding_x": -1, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "", "text_vertical_align": 1, "text_horizontal_align": 1, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": [{"name": "LeftSide", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Top", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 2, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "RecepeterData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "ReceptorIcon", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "ReceptorText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Receptor:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}, {"name": "LigandData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "LigandIcon", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "LigandText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Ligand:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}, {"name": "SiteData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "SiteIcon", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "SiteText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Site:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}]}, {"name": "Bot", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 4, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Tabs", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.270000010728836, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Receptor", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "ReceptorButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Receptor", "text_value_selected": "Receptor", "text_value_highlighted": "Receptor", "text_value_selected_highlighted": "Receptor", "text_value_unusable": "Receptor", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.280000001192093, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Ligand", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "LigandButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Ligand", "text_value_selected": "Ligand", "text_value_highlighted": "Ligand", "text_value_selected_highlighted": "Ligand", "text_value_unusable": "Ligand", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Site", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "SiteButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Site", "text_value_selected": "Site", "text_value_highlighted": "Site", "text_value_selected_highlighted": "Site", "text_value_unusable": "Site", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}]}, {"name": "List", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0.00999999977648258, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Mesh", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"mesh_color": 691685119, "type_name": "Mesh"}, "children": []}, {"name": "ComplexList", "enabled": true, "layer": 1, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0.00999999977648258, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"display_columns": 1, "display_rows": 3, "total_columns": 1, "unusable": false, "type_name": "List"}, "children": []}]}]}]}, {"name": "RightSide", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.75, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "GridResolution", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Grid Res.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "GridResolutionInput", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 5, "placeholder_text": "2.5", "input_text": "2.5", "type_name": "Text Input"}, "children": []}]}, {"name": "PosesCount", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Poses ct.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "PosesCountInput", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 3, "placeholder_text": "128", "input_text": "128", "type_name": "Text Input"}, "children": []}]}, {"name": "RotamerCount", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Rotamer ct.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "RotamerCountInput", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 2, "placeholder_text": "6", "input_text": "6", "type_name": "Text Input"}, "children": []}]}, {"name": "AlignAfter", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Align After", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "AlignButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "off", "text_value_selected": "on", "text_value_highlighted": "off", "text_value_selected_highlighted": "on", "text_value_unusable": "off", "text_auto_size": true, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "IgnoreHet", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Ignore Het.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.330000013113022, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "IgnoreHetButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "off", "text_value_selected": "on", "text_value_highlighted": "off", "text_value_selected_highlighted": "on", "text_value_unusable": "off", "text_auto_size": true, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Run", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "RunButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Run", "text_value_selected": "Run", "text_value_highlighted": "Run", "text_value_selected_highlighted": "Run", "text_value_unusable": "Running...", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.430000007152557, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Logo", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1.5, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "LogoImage", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": []}]}]}]}} \ No newline at end of file +{"title": "Docking", "version": 0, "width": 0.829999983310699, "height": 0.600000023841858, "is_menu": true, "effective_root": {"name": "Root", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 1, "forward_dist": 0, "padding_type": 1, "padding_x": -1, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "", "text_vertical_align": 1, "text_horizontal_align": 1, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": [{"name": "LeftSide", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Top", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 2, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "RecepeterData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "ReceptorIcon", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "ReceptorText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Receptor:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}, {"name": "LigandData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "LigandIcon", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "LigandText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Ligand:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}, {"name": "SiteData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "SiteIcon", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "SiteText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Site:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}]}, {"name": "Bot", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 4, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Tabs", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.270000010728836, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Receptor", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "ReceptorButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Receptor", "text_value_selected": "Receptor", "text_value_highlighted": "Receptor", "text_value_selected_highlighted": "Receptor", "text_value_unusable": "Receptor", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.280000001192093, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Ligand", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "LigandButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Ligand", "text_value_selected": "Ligand", "text_value_highlighted": "Ligand", "text_value_selected_highlighted": "Ligand", "text_value_unusable": "Ligand", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Site", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "SiteButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Site", "text_value_selected": "Site", "text_value_highlighted": "Site", "text_value_selected_highlighted": "Site", "text_value_unusable": "Site", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}]}, {"name": "List", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0.00999999977648258, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Mesh", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"mesh_color": 691685119, "type_name": "Mesh"}, "children": []}, {"name": "ComplexList", "enabled": true, "layer": 1, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0.00999999977648258, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"display_columns": 1, "display_rows": 3, "total_columns": 1, "unusable": false, "type_name": "List"}, "children": []}]}]}]}, {"name": "RightSide", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.75, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "GridResolution", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Grid Res.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "GridResolutionInput", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 5, "placeholder_text": "2.5", "input_text": "2.5", "type_name": "Text Input"}, "children": []}]}, {"name": "PosesCount", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Poses ct.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "PosesCountInput", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 3, "placeholder_text": "128", "input_text": "128", "type_name": "Text Input"}, "children": []}]}, {"name": "RotamerCount", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Rotamer ct.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "RotamerCountInput", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 2, "placeholder_text": "6", "input_text": "6", "type_name": "Text Input"}, "children": []}]}, {"name": "AlignAfter", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Align After", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "AlignButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "off", "text_value_selected": "on", "text_value_highlighted": "off", "text_value_selected_highlighted": "on", "text_value_unusable": "off", "text_auto_size": true, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "IgnoreHet", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Ignore Het.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.330000013113022, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "IgnoreHetButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "off", "text_value_selected": "on", "text_value_highlighted": "off", "text_value_selected_highlighted": "on", "text_value_unusable": "off", "text_auto_size": true, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Run", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "RunButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Run", "text_value_selected": "Run", "text_value_highlighted": "Run", "text_value_selected_highlighted": "Run", "text_value_unusable": "Running...", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.430000007152557, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Logo", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1.5, "forward_dist": 0, "padding_type": 0, "padding_x": 0.01, "padding_y": 0, "padding_z": 0.01, "padding_w": 0, "content": null, "children": [{"name": "LogoImage", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": []}]}]}]}} \ No newline at end of file From fcee1cc4b760a6354ff72fb256f9dce923bd9a71 Mon Sep 17 00:00:00 2001 From: Max Howard Date: Fri, 11 Oct 2019 13:58:57 -0700 Subject: [PATCH 07/19] Fixed some things for smina --- nanome_docking/Docking.py | 8 +-- nanome_docking/_DockingCalculations.py | 70 ++++++++++++------- .../_DockingCalculationsAutodock4.py | 3 +- nanome_docking/_DockingMenu.py | 32 +++++---- 4 files changed, 70 insertions(+), 43 deletions(-) diff --git a/nanome_docking/Docking.py b/nanome_docking/Docking.py index 3208601..e9baa3f 100644 --- a/nanome_docking/Docking.py +++ b/nanome_docking/Docking.py @@ -81,7 +81,7 @@ def on_complexes_received(complexes): Docking.convert_atoms_to_absolute_position(ligand) for molecule in ligand.molecules: ligands.add_molecule(molecule) - self._calculations.start_docking(receptor, ligands, site, params) + self._calculations.start_docking(receptor, ligands, site, **params) # Request complexes to Nanome in this order: [receptor, site (if any), ligand, ligand,...] request_list = [receptor.index] @@ -106,10 +106,10 @@ def convert_atoms_to_relative_position(complex, reference): def update(self): self._calculations.update() - def add_result_to_workspace(self, result): - for complex in result: + def add_result_to_workspace(self, results): + for complex in results: Docking.convert_atoms_to_relative_position(complex, self._receptor) - self.add_to_workspace(result) + self.add_to_workspace(results) def display_scoring_result(self, result): self._menu.display_scoring_result(result) diff --git a/nanome_docking/_DockingCalculations.py b/nanome_docking/_DockingCalculations.py index 18d83e9..5f31ae2 100644 --- a/nanome_docking/_DockingCalculations.py +++ b/nanome_docking/_DockingCalculations.py @@ -1,3 +1,5 @@ +import traceback + import nanome import gzip import itertools @@ -38,29 +40,24 @@ def __init__(self, plugin): self._plugin = plugin self._request_pending = False self._running = False + self._started_conversion = False + self._started_docking = False def initialize(self): - self._protein_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb") + self._receptor_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb") self._ligands_input = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf") + self._ligands_pdb_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb") self._site_input = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf") self._docking_output = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf.gz") self._ligand_output = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf") self._log_file = tempfile.NamedTemporaryFile(delete=False) def start_docking(self, receptor, ligands, site, exhaustiveness, modes, align, replace, scoring, autobox): - self.initialize() - - # Save all input files - receptor.io.to_pdb(self._protein_input.name, PDBOPTIONS) - nanome.util.Logs.debug("Saved PDB", self._protein_input.name) - ligands.io.to_sdf(self._ligands_input.name, SDFOPTIONS) - nanome.util.Logs.debug("Saved SDF", self._ligands_input.name) - site.io.to_sdf(self._site_input.name, SDFOPTIONS) - nanome.util.Logs.debug("Saved SDF", self._site_input.name) - self._exhaustiveness = exhaustiveness self._modes = modes self._receptor = receptor + self._ligands = ligands + self._site = site self._align = align self._replace = replace self._scoring = scoring @@ -68,23 +65,47 @@ def start_docking(self, receptor, ligands, site, exhaustiveness, modes, align, r # Start docking process self._running = False + self._started_conversion = False self._request_pending = True def update(self): if self._request_pending == False: return - if self._running == False: + if not self._running and not self._started_conversion: + self._start_converting() + self._started_conversion = True + elif self._check_conversion() and not self._started_docking: self._start_docking() + self._started_docking = True elif self._check_docking(): self._docking_finished() + def _start_converting(self): + self.initialize() + # Save all input files + self._receptor.io.to_pdb(self._receptor_input.name, PDBOPTIONS) + nanome.util.Logs.debug("Saved PDB", self._receptor_input.name) + self._ligands.io.to_sdf(self._ligands_input.name, SDFOPTIONS) + nanome.util.Logs.debug("Saved SDF", self._ligands_input.name) + self._site.io.to_sdf(self._site_input.name, SDFOPTIONS) + nanome.util.Logs.debug("Saved SDF", self._site_input.name) + + args = ['obabel', '-isdf', self._ligands_input.name, '-opdb', '-O' + self._ligands_pdb_input.name] + self._obabel_process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + def _check_conversion(self): + poll = self._obabel_process.poll() + if poll == None: + self._obabel_process.communicate() + return poll != None + def _start_docking(self): exe_path = os.path.join(os.path.dirname(__file__), 'smina') if self._scoring: - smina_args = [exe_path, '--autobox_ligand', self._site_input.name, '--score_only', '-r', self._protein_input.name, '--ligand', self._ligands_input.name, '--out', self._ligand_output.name] + smina_args = [exe_path, '--autobox_ligand', self._site_input.name, '--score_only', '-r', self._receptor_input.name, '--ligand', self._ligands_input.name, '--out', self._ligand_output.name] else: - smina_args = [exe_path, '--autobox_ligand', self._site_input.name, '-r', self._protein_input.name, '--ligand', self._ligands_input.name, '--out', \ + smina_args = [exe_path, '--autobox_ligand', self._site_input.name, '-r', self._receptor_input.name, '--ligand', self._ligands_pdb_input.name, '--out', \ self._docking_output.name, '--log', self._log_file.name, '--exhaustiveness', str(self._exhaustiveness), '--num_modes', str(self._modes), '--autobox_add', '+' + str(self._autobox)] nanome.util.Logs.debug("Run SMINA") @@ -107,6 +128,7 @@ def _check_docking(self): def _reassemble_ligs(self): generators = parse_molecules(self._docking_output.name) + fout = open(self._ligand_output.name, 'w') try: @@ -124,18 +146,16 @@ def _docking_finished(self): end = timer() nanome.util.Logs.debug("Docking Finished in", end - self._start_timer, "seconds") self._request_pending = False - try: (results, errors) = self._smina_process.communicate() if len(errors) == 0: - for result in results: - for line in result.split('\n'): - nanome.util.Logs.debug(line) + for line in results.decode().splitlines(): + nanome.util.Logs.debug(line) else: - for line in errors.splitlines(): + for line in errors.decode().splitlines(): nanome.util.Logs.warning(line.decode("utf-8")) - except: - pass + except Exception as e: + print(traceback.format_exc()) if not self._scoring: self._reassemble_ligs() @@ -146,8 +166,10 @@ def _docking_finished(self): docked_ligands.molecular.name = "Docking" docked_ligands.rendering.visible = True if self._align == True: - docked_ligands.transform.position = self._receptor.transform.position - docked_ligands.transform.rotation = self._receptor.transform.rotation + mat = self._site.transform.get_complex_to_workspace_matrix() + docked_ligands.transform.position = self._site.transform.position + docked_ligands.transform.rotation = self._site.transform.rotation + self._site.transform.position = self._site.transform.position docked_ligands.rendering.boxed = True self._plugin.make_plugin_usable() @@ -161,7 +183,7 @@ def _docking_finished(self): self._docking_output.close() self._ligand_output.close() self._log_file.close() - os.remove(self._protein_input.name) + os.remove(self._receptor_input.name) os.remove(self._ligands_input.name) os.remove(self._site_input.name) os.remove(self._docking_output.name) diff --git a/nanome_docking/_DockingCalculationsAutodock4.py b/nanome_docking/_DockingCalculationsAutodock4.py index 4114eb6..0f8f797 100644 --- a/nanome_docking/_DockingCalculationsAutodock4.py +++ b/nanome_docking/_DockingCalculationsAutodock4.py @@ -266,10 +266,9 @@ def _docking_finished(self): # Add Bonds def _start_bonds(self): - args = ['obabel', '-ipdb', self._ligands_output.name, '-osdf', '-O' + self._bond_output.name] - nanome.util.Logs.debug("Start Bonds") self._start_timer = timer() + args = ['obabel', '-ipdb', self._ligands_output.name, '-osdf', '-O' + self._bond_output.name] self._obabel_process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) self._running = True diff --git a/nanome_docking/_DockingMenu.py b/nanome_docking/_DockingMenu.py index 0fa2a55..a8f999e 100644 --- a/nanome_docking/_DockingMenu.py +++ b/nanome_docking/_DockingMenu.py @@ -11,13 +11,20 @@ def __init__(self, docking_plugin): self._selected_site = None self._exhaustiveness = 8 self._modes = 9 - self._autobox_size = 4 + self._autobox = 4 self._run_button = None self._align = True self._replace = False - self._scoring_only = False + self._scoring = False self._tab = None self._autobox_enabled = True + + def get_params(self): + params = {"exhaustiveness": None, "modes": None, "align": None, "replace": None, "scoring": None, "autobox": None} + for key, value in params.items(): + newvalue = getattr(self, "_"+key) + params[key] = newvalue + return params def _run_docking(self): if self._selected_receptor == None or len(self._selected_ligands) == 0: @@ -30,7 +37,7 @@ def _run_docking(self): site = None if self._autobox_enabled: site = self._selected_site.complex - self._plugin.run_docking(self._selected_receptor.complex, ligands, site) + self._plugin.run_docking(self._selected_receptor.complex, ligands, site, self.get_params()) def disable_autobox(self): self._site_btn.unusable = True @@ -122,7 +129,7 @@ def display_scoring_result(self, result): def build_menu(self): # defining callbacks def run_button_pressed_callback(button): - if self._scoring_only: + if self._scoring: self._docking_param_panel.enabled = False self._score_panel.enabled = True self._score_list.items = [] @@ -149,12 +156,12 @@ def modes_changed(input): def autobox_changed(input): try: - self._autobox_size = int(input.input_text) - nanome.util.Logs.debug("Autobox size set to", self._autobox_size) + self._autobox = int(input.input_text) + nanome.util.Logs.debug("Autobox size set to", self._autobox) except: - self._autobox_size = 4 - if self._autobox_size <= 0: - self._autobox_size = 4 + self._autobox = 4 + if self._autobox <= 0: + self._autobox = 4 def tab_button_pressed_callback(button): if self._tab == button: @@ -199,21 +206,20 @@ def close_score_pressed_callback(button): self._plugin.update_menu(self._menu) def scoring_button_pressed_callback(button): - self._scoring_only = not self._scoring_only - button.selected = self._scoring_only + self._scoring = not self._scoring + button.selected = self._scoring self._plugin.update_content(button) # Create a prefab that will be used to populate the lists self._complex_item_prefab = nanome.ui.LayoutNode() self._complex_item_prefab.layout_orientation = nanome.ui.LayoutNode.LayoutTypes.horizontal child = self._complex_item_prefab.create_child_node() - child.forward_dist = 0.002 child.add_new_button() self._score_item_prefab = nanome.ui.LayoutNode() self._score_item_prefab.layout_orientation = nanome.ui.LayoutNode.LayoutTypes.horizontal child = self._score_item_prefab.create_child_node() - child.forward_dist = 0.002 + # child.forward_dist = 0.002 child.add_new_label() # loading menus From 12ab6eb670c9527637d480f916319f98b2d1e1eb Mon Sep 17 00:00:00 2001 From: Max Howard Date: Fri, 11 Oct 2019 17:24:39 -0700 Subject: [PATCH 08/19] Smina docking ligand box aligned with site box --- nanome_docking/Docking.py | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/nanome_docking/Docking.py b/nanome_docking/Docking.py index e9baa3f..738a891 100644 --- a/nanome_docking/Docking.py +++ b/nanome_docking/Docking.py @@ -74,6 +74,8 @@ def on_complexes_received(complexes): site = None if has_site: site = complexes[1] + self._site = site + self._site_wtc_mat = site.get_workspace_to_complex_matrix() Docking.convert_atoms_to_absolute_position(site) starting_lig_idx = 2 ligands = nanome.structure.Complex() @@ -92,29 +94,45 @@ def on_complexes_received(complexes): @staticmethod def convert_atoms_to_absolute_position(complex): - mat = complex.transform.get_complex_to_workspace_matrix() + mat = complex.get_complex_to_workspace_matrix() for atom in complex.atoms: - atom.molecular.position = mat * atom.molecular.position + atom.position = mat * atom.position @staticmethod - def convert_atoms_to_relative_position(complex, reference): - mat = reference.transform.get_workspace_to_complex_matrix() + def convert_atoms_to_relative_position(complex, mat): + # mat = reference.get_workspace_to_complex_matrix() for atom in complex.atoms: - atom.molecular.position = mat * atom.molecular.position + atom.position = mat * atom.position # Called every update tick of the Plugin def update(self): self._calculations.update() - def add_result_to_workspace(self, results): + def add_result_to_workspace(self, results, align=False): for complex in results: - Docking.convert_atoms_to_relative_position(complex, self._receptor) + # reference = site if site != None else self._receptor + # print("reference:", [chain.name for chain in reference.chains]) + Docking.convert_atoms_to_relative_position(complex, self._site_wtc_mat) + + if align: + # get global atom pos + mat = complex.get_complex_to_workspace_matrix() + global_pos = [mat * atom.position for atom in complex.atoms] + # align bounding box + complex.position = self._site.position + complex.rotation = self._site.rotation + # restore atom pos + mat = complex.get_workspace_to_complex_matrix() + for (atom, pos) in zip(complex.atoms, global_pos): + atom.position = mat * pos + + complex.boxed = True + self.add_to_workspace(results) def display_scoring_result(self, result): self._menu.display_scoring_result(result) - class SminaDocking(Docking): def __init__(self): super(SminaDocking, self).__init__() From e7d635e575512038e8eff000a4c7f9e8a73ee834 Mon Sep 17 00:00:00 2001 From: Max Howard Date: Thu, 17 Oct 2019 13:55:12 -0700 Subject: [PATCH 09/19] current progress --- nanome_docking/Docking.py | 34 ++++++------- nanome_docking/_DockingCalculations.py | 68 ++++++++++++++++---------- nanome_docking/_DockingMenu.py | 32 +++++++++++- 3 files changed, 88 insertions(+), 46 deletions(-) diff --git a/nanome_docking/Docking.py b/nanome_docking/Docking.py index 738a891..5fa9191 100644 --- a/nanome_docking/Docking.py +++ b/nanome_docking/Docking.py @@ -8,6 +8,16 @@ __metaclass__ = type +def convert_atoms_to_absolute_position(complex): + mat = complex.get_complex_to_workspace_matrix() + for atom in complex.atoms: + atom.position = mat * atom.position + +def convert_atoms_to_relative_position(complex, mat): + # mat = reference.get_workspace_to_complex_matrix() + for atom in complex.atoms: + atom.position = mat * atom.position + class Docking(nanome.PluginInstance): def __init__(self): @@ -69,18 +79,18 @@ def on_complexes_received(complexes): # When deep complexes data are received, unpack them and prepare ligand for docking receptor = complexes[0] self._receptor = receptor - Docking.convert_atoms_to_absolute_position(receptor) + convert_atoms_to_absolute_position(receptor) starting_lig_idx = 1 site = None if has_site: site = complexes[1] self._site = site self._site_wtc_mat = site.get_workspace_to_complex_matrix() - Docking.convert_atoms_to_absolute_position(site) + convert_atoms_to_absolute_position(site) starting_lig_idx = 2 ligands = nanome.structure.Complex() for ligand in complexes[starting_lig_idx:]: - Docking.convert_atoms_to_absolute_position(ligand) + convert_atoms_to_absolute_position(ligand) for molecule in ligand.molecules: ligands.add_molecule(molecule) self._calculations.start_docking(receptor, ligands, site, **params) @@ -92,18 +102,6 @@ def on_complexes_received(complexes): request_list += [x.index for x in ligands] self.request_complexes(request_list, on_complexes_received) - @staticmethod - def convert_atoms_to_absolute_position(complex): - mat = complex.get_complex_to_workspace_matrix() - for atom in complex.atoms: - atom.position = mat * atom.position - - @staticmethod - def convert_atoms_to_relative_position(complex, mat): - # mat = reference.get_workspace_to_complex_matrix() - for atom in complex.atoms: - atom.position = mat * atom.position - # Called every update tick of the Plugin def update(self): self._calculations.update() @@ -112,11 +110,11 @@ def add_result_to_workspace(self, results, align=False): for complex in results: # reference = site if site != None else self._receptor # print("reference:", [chain.name for chain in reference.chains]) - Docking.convert_atoms_to_relative_position(complex, self._site_wtc_mat) - + convert_atoms_to_relative_position(complex, self._site_wtc_mat) + if align: - # get global atom pos mat = complex.get_complex_to_workspace_matrix() + # get global atom pos global_pos = [mat * atom.position for atom in complex.atoms] # align bounding box complex.position = self._site.position diff --git a/nanome_docking/_DockingCalculations.py b/nanome_docking/_DockingCalculations.py index 5f31ae2..3049154 100644 --- a/nanome_docking/_DockingCalculations.py +++ b/nanome_docking/_DockingCalculations.py @@ -1,6 +1,7 @@ import traceback import nanome +import shutil import gzip import itertools import operator @@ -12,6 +13,8 @@ from nanome.util.enums import NotificationTypes +DEBUG = True + SDFOPTIONS = nanome.api.structure.Complex.io.SDFSaveOptions() SDFOPTIONS.write_bonds = True PDBOPTIONS = nanome.api.structure.Complex.io.PDBSaveOptions() @@ -23,11 +26,17 @@ except: pass +def dprint(*msg): + if DEBUG: + print(*msg) + def not_dollars(line): return b'$$$$' != line.strip(b'\n') -def parse_molecules(file): +def parse_molecules(file, self): + dprint("parsing output...") nanome.util.Logs.debug("Parsing output", file) + print("file:", file) with gzip.open(file) as lines: while True: block = list(itertools.takewhile(not_dollars, lines )) @@ -43,14 +52,19 @@ def __init__(self, plugin): self._started_conversion = False self._started_docking = False + dprint("flags set") + def initialize(self): - self._receptor_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb") - self._ligands_input = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf") - self._ligands_pdb_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb") - self._site_input = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf") - self._docking_output = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf.gz") - self._ligand_output = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf") - self._log_file = tempfile.NamedTemporaryFile(delete=False) + self.temp_dir = tempfile.TemporaryDirectory() + self._receptor_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb", dir=self.temp_dir.name) + self._ligands_input = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf", dir=self.temp_dir.name) + self._ligands_pdb_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb", dir=self.temp_dir.name) + self._site_input = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf", dir=self.temp_dir.name) + self._docking_output = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf.gz", dir=self.temp_dir.name) + self._ligand_output = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf", dir=self.temp_dir.name) + self._log_file = tempfile.NamedTemporaryFile(delete=False, dir=self.temp_dir.name) + + dprint("temp files created") def start_docking(self, receptor, ligands, site, exhaustiveness, modes, align, replace, scoring, autobox): self._exhaustiveness = exhaustiveness @@ -66,10 +80,14 @@ def start_docking(self, receptor, ligands, site, exhaustiveness, modes, align, r # Start docking process self._running = False self._started_conversion = False + self._started_docking = False self._request_pending = True + dprint("starting docking...") + def update(self): if self._request_pending == False: + # dprint("request not pending, doing nothing") return if not self._running and not self._started_conversion: @@ -82,6 +100,7 @@ def update(self): self._docking_finished() def _start_converting(self): + dprint("beginning input file conversion...") self.initialize() # Save all input files self._receptor.io.to_pdb(self._receptor_input.name, PDBOPTIONS) @@ -101,12 +120,13 @@ def _check_conversion(self): return poll != None def _start_docking(self): + dprint("starting docking...") exe_path = os.path.join(os.path.dirname(__file__), 'smina') if self._scoring: - smina_args = [exe_path, '--autobox_ligand', self._site_input.name, '--score_only', '-r', self._receptor_input.name, '--ligand', self._ligands_input.name, '--out', self._ligand_output.name] + smina_args = [exe_path, '-r', self._receptor_input.name, '-l', self._ligands_input.name, '--autobox_ligand', self._site_input.name, '--score_only', '--out', self._ligand_output.name] else: - smina_args = [exe_path, '--autobox_ligand', self._site_input.name, '-r', self._receptor_input.name, '--ligand', self._ligands_pdb_input.name, '--out', \ - self._docking_output.name, '--log', self._log_file.name, '--exhaustiveness', str(self._exhaustiveness), '--num_modes', str(self._modes), '--autobox_add', '+' + str(self._autobox)] + smina_args = [exe_path, '-r', self._receptor_input.name, '-l', self._ligands_pdb_input.name, '--autobox_ligand', self._site_input.name, '--out', \ + self._docking_output.name, '--log', self._log_file.name, '--exhaustiveness', str(self._exhaustiveness), '--num_modes', str(self._modes), '--autobox_add', str(self._autobox), '--seed', '0'] nanome.util.Logs.debug("Run SMINA") self._start_timer = timer() @@ -127,7 +147,8 @@ def _check_docking(self): return self._smina_process.poll() != None def _reassemble_ligs(self): - generators = parse_molecules(self._docking_output.name) + dprint("reassembling ligands...") + generators = parse_molecules(self._docking_output.name, self) fout = open(self._ligand_output.name, 'w') @@ -143,6 +164,8 @@ def _reassemble_ligs(self): fout.close() def _docking_finished(self): + dprint("finishing docking...") + dprint("docking output:", self._docking_output.name) end = timer() nanome.util.Logs.debug("Docking Finished in", end - self._start_timer, "seconds") self._request_pending = False @@ -150,10 +173,12 @@ def _docking_finished(self): (results, errors) = self._smina_process.communicate() if len(errors) == 0: for line in results.decode().splitlines(): + print("result line:", line) nanome.util.Logs.debug(line) else: for line in errors.decode().splitlines(): - nanome.util.Logs.warning(line.decode("utf-8")) + print("error line:", line) + nanome.util.Logs.warning(line) except Exception as e: print(traceback.format_exc()) @@ -165,29 +190,18 @@ def _docking_finished(self): if not self._scoring: docked_ligands.molecular.name = "Docking" docked_ligands.rendering.visible = True - if self._align == True: - mat = self._site.transform.get_complex_to_workspace_matrix() - docked_ligands.transform.position = self._site.transform.position - docked_ligands.transform.rotation = self._site.transform.rotation - self._site.transform.position = self._site.transform.position - docked_ligands.rendering.boxed = True - + self._plugin.make_plugin_usable() if self._scoring: nanome.util.Logs.debug("Display scoring result") self._plugin.display_scoring_result(docked_ligands) else: nanome.util.Logs.debug("Update workspace") - self._plugin.add_result_to_workspace([docked_ligands]) + self._plugin.add_result_to_workspace([docked_ligands], self._align) self._docking_output.close() self._ligand_output.close() self._log_file.close() - os.remove(self._receptor_input.name) - os.remove(self._ligands_input.name) - os.remove(self._site_input.name) - os.remove(self._docking_output.name) - os.remove(self._ligand_output.name) - os.remove(self._log_file.name) + # shutil.rmtree(self.temp_dir.name) self._plugin.send_notification(NotificationTypes.success, "Docking finished") diff --git a/nanome_docking/_DockingMenu.py b/nanome_docking/_DockingMenu.py index a8f999e..08899c4 100644 --- a/nanome_docking/_DockingMenu.py +++ b/nanome_docking/_DockingMenu.py @@ -13,6 +13,7 @@ def __init__(self, docking_plugin): self._modes = 9 self._autobox = 4 self._run_button = None + self._run_button = None self._align = True self._replace = False self._scoring = False @@ -49,7 +50,7 @@ def disable_autobox(self): self._plugin.update_menu(self._menu) def make_plugin_usable(self, state=True): - self._run_button.unusable = not state + self._run_button.unusable = not state | self.refresh_run_btn_enabled(False) self._plugin.update_content(self._run_button) def receptor_pressed(self, button): @@ -63,6 +64,8 @@ def receptor_pressed(self, button): self._receptor_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'checkmark.png') self._plugin.update_content(self._receptor_checkmark) + self.refresh_run_btn_enabled() + def ligand_pressed(self, button): if button.selected == False: button.selected = True @@ -77,6 +80,8 @@ def ligand_pressed(self, button): self._ligand_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'none.png') self._plugin.update_content(self._ligand_checkmark) + self.refresh_run_btn_enabled() + def site_pressed(self, button): lastSelected = self._selected_site if lastSelected != None: @@ -87,6 +92,21 @@ def site_pressed(self, button): self._plugin.update_content(button) self._site_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'checkmark.png') self._plugin.update_content(self._site_checkmark) + + self.refresh_run_btn_enabled() + + def refresh_run_btn_enabled(self, update=True): + if self._selected_receptor != None and len(self._selected_ligands) > 0 and self._selected_site != None: + self._run_button.text.value_unusable = "Running..." + self._run_button.unusable = False + else: + self._run_button.text.value_unusable = "Run" + self._run_button.unusable = True + + if update: + self._plugin.update_content(self._run_button) + + return self._run_button.unusable def change_complex_list(self, complex_list): def complex_pressed(button): @@ -117,6 +137,8 @@ def complex_pressed(button): self._plugin.update_menu(self._menu) def display_scoring_result(self, result): + self.reset_menu() + for molecule in result.molecules: clone = self._score_item_prefab.clone() ln_lbl = clone.get_children()[0] @@ -124,6 +146,12 @@ def display_scoring_result(self, result): lbl.text_value = molecule.molecular.name + " - " + molecule._associated["> "] self._score_list.items.append(clone) + def reset_menu(self): + self._selected_receptor = None + self._selected_ligands = [] + self._selected_site == None + + self.make_plugin_usable() self._plugin.update_menu(self._menu) def build_menu(self): @@ -276,6 +304,8 @@ def scoring_button_pressed_callback(button): run_button = menu.root.find_node("RunButton", True).get_content() run_button.register_pressed_callback(run_button_pressed_callback) self._run_button = run_button + self._run_button.enabled = False + self.refresh_run_btn_enabled() # lists self._complex_list = menu.root.find_node("ComplexList", True).get_content() From 0cebc974746142a196cf3e943c8b61eacc36f5c0 Mon Sep 17 00:00:00 2001 From: Max Howard Date: Thu, 17 Oct 2019 16:13:00 -0700 Subject: [PATCH 10/19] :) --- nanome_docking/Docking.py | 11 +++-- nanome_docking/_DockingCalculations.py | 65 ++++++++++++++------------ nanome_docking/_DockingMenu.py | 2 +- 3 files changed, 43 insertions(+), 35 deletions(-) diff --git a/nanome_docking/Docking.py b/nanome_docking/Docking.py index 5fa9191..de7727c 100644 --- a/nanome_docking/Docking.py +++ b/nanome_docking/Docking.py @@ -79,18 +79,20 @@ def on_complexes_received(complexes): # When deep complexes data are received, unpack them and prepare ligand for docking receptor = complexes[0] self._receptor = receptor - convert_atoms_to_absolute_position(receptor) + # convert_atoms_to_absolute_position(receptor) + m_workspace_to_receptor = receptor.get_workspace_to_complex_matrix() starting_lig_idx = 1 site = None if has_site: site = complexes[1] self._site = site - self._site_wtc_mat = site.get_workspace_to_complex_matrix() convert_atoms_to_absolute_position(site) + convert_atoms_to_relative_position(site, m_workspace_to_receptor) starting_lig_idx = 2 ligands = nanome.structure.Complex() for ligand in complexes[starting_lig_idx:]: convert_atoms_to_absolute_position(ligand) + convert_atoms_to_relative_position(ligand, m_workspace_to_receptor) for molecule in ligand.molecules: ligands.add_molecule(molecule) self._calculations.start_docking(receptor, ligands, site, **params) @@ -110,8 +112,9 @@ def add_result_to_workspace(self, results, align=False): for complex in results: # reference = site if site != None else self._receptor # print("reference:", [chain.name for chain in reference.chains]) - convert_atoms_to_relative_position(complex, self._site_wtc_mat) - + complex.position = self._receptor.position + complex.rotation = self._receptor.rotation + if align: mat = complex.get_complex_to_workspace_matrix() # get global atom pos diff --git a/nanome_docking/_DockingCalculations.py b/nanome_docking/_DockingCalculations.py index 3049154..48571bd 100644 --- a/nanome_docking/_DockingCalculations.py +++ b/nanome_docking/_DockingCalculations.py @@ -31,25 +31,25 @@ def dprint(*msg): print(*msg) def not_dollars(line): - return b'$$$$' != line.strip(b'\n') + return '$$$$' != line.strip('\n') def parse_molecules(file, self): dprint("parsing output...") nanome.util.Logs.debug("Parsing output", file) print("file:", file) - with gzip.open(file) as lines: + with open(file) as lines: while True: block = list(itertools.takewhile(not_dollars, lines )) if not block: break - yield block + [b'$$$$\n'] + yield block + ['$$$$\n'] class DockingCalculations(): def __init__(self, plugin): self._plugin = plugin self._request_pending = False self._running = False - self._started_conversion = False + self._structures_written = False self._started_docking = False dprint("flags set") @@ -57,11 +57,11 @@ def __init__(self, plugin): def initialize(self): self.temp_dir = tempfile.TemporaryDirectory() self._receptor_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb", dir=self.temp_dir.name) - self._ligands_input = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf", dir=self.temp_dir.name) + self._ligands_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb", dir=self.temp_dir.name) self._ligands_pdb_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb", dir=self.temp_dir.name) - self._site_input = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf", dir=self.temp_dir.name) - self._docking_output = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf.gz", dir=self.temp_dir.name) - self._ligand_output = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf", dir=self.temp_dir.name) + self._site_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb", dir=self.temp_dir.name) + self._docking_output = tempfile.NamedTemporaryFile(delete=False, prefix="output", suffix=".sdf", dir=self.temp_dir.name) + self._ligand_output = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb", dir=self.temp_dir.name) self._log_file = tempfile.NamedTemporaryFile(delete=False, dir=self.temp_dir.name) dprint("temp files created") @@ -79,7 +79,7 @@ def start_docking(self, receptor, ligands, site, exhaustiveness, modes, align, r # Start docking process self._running = False - self._started_conversion = False + self._structures_written = False self._started_docking = False self._request_pending = True @@ -90,28 +90,25 @@ def update(self): # dprint("request not pending, doing nothing") return - if not self._running and not self._started_conversion: - self._start_converting() - self._started_conversion = True - elif self._check_conversion() and not self._started_docking: + if not self._running and not self._structures_written: + self.write_structures_to_file() + self._structures_written = True + elif not self._started_docking: self._start_docking() self._started_docking = True elif self._check_docking(): self._docking_finished() - def _start_converting(self): + def write_structures_to_file(self): dprint("beginning input file conversion...") self.initialize() # Save all input files self._receptor.io.to_pdb(self._receptor_input.name, PDBOPTIONS) nanome.util.Logs.debug("Saved PDB", self._receptor_input.name) - self._ligands.io.to_sdf(self._ligands_input.name, SDFOPTIONS) + self._ligands.io.to_pdb(self._ligands_input.name, PDBOPTIONS) nanome.util.Logs.debug("Saved SDF", self._ligands_input.name) - self._site.io.to_sdf(self._site_input.name, SDFOPTIONS) + self._site.io.to_pdb(self._site_input.name, PDBOPTIONS) nanome.util.Logs.debug("Saved SDF", self._site_input.name) - - args = ['obabel', '-isdf', self._ligands_input.name, '-opdb', '-O' + self._ligands_pdb_input.name] - self._obabel_process = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) def _check_conversion(self): poll = self._obabel_process.poll() @@ -122,17 +119,27 @@ def _check_conversion(self): def _start_docking(self): dprint("starting docking...") exe_path = os.path.join(os.path.dirname(__file__), 'smina') + + receptor_input_name = os.path.join(os.path.dirname(__file__), '1OYT-receptor.pdb') + ligand_input_name = os.path.join(os.path.dirname(__file__), '1OYT-FSN.pdb') + if self._scoring: smina_args = [exe_path, '-r', self._receptor_input.name, '-l', self._ligands_input.name, '--autobox_ligand', self._site_input.name, '--score_only', '--out', self._ligand_output.name] else: - smina_args = [exe_path, '-r', self._receptor_input.name, '-l', self._ligands_pdb_input.name, '--autobox_ligand', self._site_input.name, '--out', \ - self._docking_output.name, '--log', self._log_file.name, '--exhaustiveness', str(self._exhaustiveness), '--num_modes', str(self._modes), '--autobox_add', str(self._autobox), '--seed', '0'] + print("receptor:", self._receptor_input.name) + print("ligands:", self._ligands_input.name) + smina_args = [exe_path, '-r', self._receptor_input.name, '-l', self._ligands_input.name, '--autobox_ligand', self._site_input.name, '--out', \ + self._docking_output.name, '--log', self._log_file.name, '--exhaustiveness', str(self._exhaustiveness), '--num_modes', str(self._modes), '--autobox_add', str(self._autobox), '--seed', '0'] + # smina_args = [exe_path, '-r', receptor_input_name, '-l', ligand_input_name, '--autobox_ligand', ligand_input_name, '--out', \ + # self._docking_output.name, '--log', self._log_file.name, '--exhaustiveness', str(self._exhaustiveness), '--num_modes', str(self._modes), '--autobox_add', str(self._autobox), '--seed', '0'] nanome.util.Logs.debug("Run SMINA") self._start_timer = timer() try: self._smina_process = subprocess.Popen(smina_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + print("started smina") except: + print("uh oh.") nanome.util.Logs.error("Couldn't execute smina, please check if executable is in the plugin folder and has permissions. Path:", SMINA_PATH) self._request_pending = False self._running = False @@ -145,17 +152,17 @@ def _start_docking(self): def _check_docking(self): return self._smina_process.poll() != None - + def _reassemble_ligs(self): dprint("reassembling ligands...") generators = parse_molecules(self._docking_output.name, self) - fout = open(self._ligand_output.name, 'w') try: for gen in generators: + print("gen:", gen) for line in gen: - str = line.decode("utf-8").strip('\n') + str = lines.strip('\n') fout.write(''.join(str)) fout.write('\n') except StopIteration: @@ -183,9 +190,10 @@ def _docking_finished(self): print(traceback.format_exc()) if not self._scoring: - self._reassemble_ligs() - docked_ligands = nanome.structure.Complex.io.from_sdf(path=self._ligand_output.name) - nanome.util.Logs.debug("Read SDF", self._ligand_output.name) + pass + # self._reassemble_ligs() + docked_ligands = nanome.structure.Complex.io.from_sdf(path=self._docking_output.name) + nanome.util.Logs.debug("Read PDB", self._docking_output.name) if not self._scoring: docked_ligands.molecular.name = "Docking" @@ -199,9 +207,6 @@ def _docking_finished(self): nanome.util.Logs.debug("Update workspace") self._plugin.add_result_to_workspace([docked_ligands], self._align) - self._docking_output.close() - self._ligand_output.close() - self._log_file.close() # shutil.rmtree(self.temp_dir.name) self._plugin.send_notification(NotificationTypes.success, "Docking finished") diff --git a/nanome_docking/_DockingMenu.py b/nanome_docking/_DockingMenu.py index 08899c4..099e5c3 100644 --- a/nanome_docking/_DockingMenu.py +++ b/nanome_docking/_DockingMenu.py @@ -129,7 +129,7 @@ def complex_pressed(button): clone = self._complex_item_prefab.clone() ln_btn = clone.get_children()[0] btn = ln_btn.get_content() - btn.set_all_text(complex.molecular.name) + btn.set_all_text(complex.full_name) btn.complex = complex btn.register_pressed_callback(complex_pressed) self._complex_list.items.append(clone) From 0dc8f76b3db24e5e8b7d3ae7f3867354ee4eb139 Mon Sep 17 00:00:00 2001 From: Max Howard Date: Fri, 18 Oct 2019 11:40:26 -0700 Subject: [PATCH 11/19] execute permissions on smina --- nanome_docking/smina | Bin 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 nanome_docking/smina diff --git a/nanome_docking/smina b/nanome_docking/smina old mode 100644 new mode 100755 From e1e457ad95a9ab5c2574a73b9f5b3293bd319778 Mon Sep 17 00:00:00 2001 From: Max Howard Date: Fri, 18 Oct 2019 11:56:23 -0700 Subject: [PATCH 12/19] removed depcrecated api calls --- nanome_docking/_DockingCalculationsAutodock4.py | 4 ++-- nanome_docking/_DockingCalculationsRhodium.py | 6 +++--- nanome_docking/_DockingMenu.py | 2 +- nanome_docking/_DockingMenuRhodium.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/nanome_docking/_DockingCalculationsAutodock4.py b/nanome_docking/_DockingCalculationsAutodock4.py index 0f8f797..49da38b 100644 --- a/nanome_docking/_DockingCalculationsAutodock4.py +++ b/nanome_docking/_DockingCalculationsAutodock4.py @@ -291,8 +291,8 @@ def _bonds_finished(self): docked_ligands = nanome.structure.Complex.io.from_sdf(path=self._bond_output.name) nanome.util.Logs.debug("Read SDF", self._bond_output.name) - docked_ligands.molecular.name = "Docking" - docked_ligands.rendering.visible = True + docked_ligands.name = "Docking" + docked_ligands.visible = True if self._align == True: docked_ligands.transform.position = self._receptor.transform.position docked_ligands.transform.rotation = self._receptor.transform.rotation diff --git a/nanome_docking/_DockingCalculationsRhodium.py b/nanome_docking/_DockingCalculationsRhodium.py index 48d7c94..7756522 100644 --- a/nanome_docking/_DockingCalculationsRhodium.py +++ b/nanome_docking/_DockingCalculationsRhodium.py @@ -150,12 +150,12 @@ def assemble_result(self, docking_output): def bonds_added(complex_arr): docked_ligands_bonded = complex_arr[0] - docked_ligands_bonded.molecular.name = "Docking" - docked_ligands_bonded.rendering.visible = True + docked_ligands_bonded.name = "Docking" + docked_ligands_bonded.visible = True if self._params['align'] == True: docked_ligands_bonded.transform.position = self._receptor.transform.position docked_ligands_bonded.transform.rotation = self._receptor.transform.rotation - docked_ligands_bonded.rendering.boxed = True + docked_ligands_bonded.boxed = True nanome.util.Logs.debug("Update workspace") self._plugin.add_result_to_workspace([docked_ligands_bonded]) diff --git a/nanome_docking/_DockingMenu.py b/nanome_docking/_DockingMenu.py index 099e5c3..4c71733 100644 --- a/nanome_docking/_DockingMenu.py +++ b/nanome_docking/_DockingMenu.py @@ -143,7 +143,7 @@ def display_scoring_result(self, result): clone = self._score_item_prefab.clone() ln_lbl = clone.get_children()[0] lbl = ln_lbl.get_content() - lbl.text_value = molecule.molecular.name + " - " + molecule._associated["> "] + lbl.text_value = molecule.name + " - " + molecule._associated["> "] self._score_list.items.append(clone) def reset_menu(self): diff --git a/nanome_docking/_DockingMenuRhodium.py b/nanome_docking/_DockingMenuRhodium.py index ebd1d54..097c728 100644 --- a/nanome_docking/_DockingMenuRhodium.py +++ b/nanome_docking/_DockingMenuRhodium.py @@ -123,7 +123,7 @@ def complex_pressed(button): clone = self._complex_item_prefab.clone() ln_btn = clone.get_children()[0] btn = ln_btn.get_content() - btn.set_all_text(complex.molecular.name) + btn.set_all_text(complex.name) btn.complex = complex btn.register_pressed_callback(complex_pressed) self._complex_list.items.append(clone) From fe14279a3e000b6db867fc9fa80ef66363a3a7b6 Mon Sep 17 00:00:00 2001 From: Max Howard Date: Fri, 18 Oct 2019 11:59:11 -0700 Subject: [PATCH 13/19] debug cleanup --- nanome_docking/_DockingCalculations.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/nanome_docking/_DockingCalculations.py b/nanome_docking/_DockingCalculations.py index 48571bd..ec5e65c 100644 --- a/nanome_docking/_DockingCalculations.py +++ b/nanome_docking/_DockingCalculations.py @@ -26,15 +26,10 @@ except: pass -def dprint(*msg): - if DEBUG: - print(*msg) - def not_dollars(line): return '$$$$' != line.strip('\n') def parse_molecules(file, self): - dprint("parsing output...") nanome.util.Logs.debug("Parsing output", file) print("file:", file) with open(file) as lines: @@ -52,7 +47,6 @@ def __init__(self, plugin): self._structures_written = False self._started_docking = False - dprint("flags set") def initialize(self): self.temp_dir = tempfile.TemporaryDirectory() @@ -64,7 +58,6 @@ def initialize(self): self._ligand_output = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb", dir=self.temp_dir.name) self._log_file = tempfile.NamedTemporaryFile(delete=False, dir=self.temp_dir.name) - dprint("temp files created") def start_docking(self, receptor, ligands, site, exhaustiveness, modes, align, replace, scoring, autobox): self._exhaustiveness = exhaustiveness @@ -83,11 +76,9 @@ def start_docking(self, receptor, ligands, site, exhaustiveness, modes, align, r self._started_docking = False self._request_pending = True - dprint("starting docking...") def update(self): if self._request_pending == False: - # dprint("request not pending, doing nothing") return if not self._running and not self._structures_written: @@ -100,7 +91,6 @@ def update(self): self._docking_finished() def write_structures_to_file(self): - dprint("beginning input file conversion...") self.initialize() # Save all input files self._receptor.io.to_pdb(self._receptor_input.name, PDBOPTIONS) @@ -117,7 +107,6 @@ def _check_conversion(self): return poll != None def _start_docking(self): - dprint("starting docking...") exe_path = os.path.join(os.path.dirname(__file__), 'smina') receptor_input_name = os.path.join(os.path.dirname(__file__), '1OYT-receptor.pdb') @@ -131,8 +120,6 @@ def _start_docking(self): smina_args = [exe_path, '-r', self._receptor_input.name, '-l', self._ligands_input.name, '--autobox_ligand', self._site_input.name, '--out', \ self._docking_output.name, '--log', self._log_file.name, '--exhaustiveness', str(self._exhaustiveness), '--num_modes', str(self._modes), '--autobox_add', str(self._autobox), '--seed', '0'] - # smina_args = [exe_path, '-r', receptor_input_name, '-l', ligand_input_name, '--autobox_ligand', ligand_input_name, '--out', \ - # self._docking_output.name, '--log', self._log_file.name, '--exhaustiveness', str(self._exhaustiveness), '--num_modes', str(self._modes), '--autobox_add', str(self._autobox), '--seed', '0'] nanome.util.Logs.debug("Run SMINA") self._start_timer = timer() try: @@ -154,7 +141,6 @@ def _check_docking(self): return self._smina_process.poll() != None def _reassemble_ligs(self): - dprint("reassembling ligands...") generators = parse_molecules(self._docking_output.name, self) fout = open(self._ligand_output.name, 'w') @@ -171,8 +157,6 @@ def _reassemble_ligs(self): fout.close() def _docking_finished(self): - dprint("finishing docking...") - dprint("docking output:", self._docking_output.name) end = timer() nanome.util.Logs.debug("Docking Finished in", end - self._start_timer, "seconds") self._request_pending = False From 405b809955cf6e7e48bb84585ebd5d04f04d7d74 Mon Sep 17 00:00:00 2001 From: Max Howard Date: Fri, 18 Oct 2019 12:23:25 -0700 Subject: [PATCH 14/19] Put back temporary file removal --- nanome_docking/_DockingCalculations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nanome_docking/_DockingCalculations.py b/nanome_docking/_DockingCalculations.py index ec5e65c..d325210 100644 --- a/nanome_docking/_DockingCalculations.py +++ b/nanome_docking/_DockingCalculations.py @@ -191,6 +191,6 @@ def _docking_finished(self): nanome.util.Logs.debug("Update workspace") self._plugin.add_result_to_workspace([docked_ligands], self._align) - # shutil.rmtree(self.temp_dir.name) + shutil.rmtree(self.temp_dir.name) self._plugin.send_notification(NotificationTypes.success, "Docking finished") From f8f6c08f750d274e3e498412a19c6d67a813655c Mon Sep 17 00:00:00 2001 From: Max Howard Date: Fri, 18 Oct 2019 13:23:14 -0700 Subject: [PATCH 15/19] cleanup and menu state correct reset --- nanome_docking/Docking.py | 2 -- nanome_docking/_DockingCalculations.py | 9 ------ .../_DockingCalculationsAutodock4.py | 3 +- nanome_docking/_DockingCalculationsRhodium.py | 3 +- nanome_docking/_DockingMenu.py | 31 +++++++++---------- 5 files changed, 19 insertions(+), 29 deletions(-) diff --git a/nanome_docking/Docking.py b/nanome_docking/Docking.py index de7727c..fe8943d 100644 --- a/nanome_docking/Docking.py +++ b/nanome_docking/Docking.py @@ -110,8 +110,6 @@ def update(self): def add_result_to_workspace(self, results, align=False): for complex in results: - # reference = site if site != None else self._receptor - # print("reference:", [chain.name for chain in reference.chains]) complex.position = self._receptor.position complex.rotation = self._receptor.rotation diff --git a/nanome_docking/_DockingCalculations.py b/nanome_docking/_DockingCalculations.py index d325210..e59af56 100644 --- a/nanome_docking/_DockingCalculations.py +++ b/nanome_docking/_DockingCalculations.py @@ -31,7 +31,6 @@ def not_dollars(line): def parse_molecules(file, self): nanome.util.Logs.debug("Parsing output", file) - print("file:", file) with open(file) as lines: while True: block = list(itertools.takewhile(not_dollars, lines )) @@ -115,8 +114,6 @@ def _start_docking(self): if self._scoring: smina_args = [exe_path, '-r', self._receptor_input.name, '-l', self._ligands_input.name, '--autobox_ligand', self._site_input.name, '--score_only', '--out', self._ligand_output.name] else: - print("receptor:", self._receptor_input.name) - print("ligands:", self._ligands_input.name) smina_args = [exe_path, '-r', self._receptor_input.name, '-l', self._ligands_input.name, '--autobox_ligand', self._site_input.name, '--out', \ self._docking_output.name, '--log', self._log_file.name, '--exhaustiveness', str(self._exhaustiveness), '--num_modes', str(self._modes), '--autobox_add', str(self._autobox), '--seed', '0'] @@ -124,9 +121,7 @@ def _start_docking(self): self._start_timer = timer() try: self._smina_process = subprocess.Popen(smina_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - print("started smina") except: - print("uh oh.") nanome.util.Logs.error("Couldn't execute smina, please check if executable is in the plugin folder and has permissions. Path:", SMINA_PATH) self._request_pending = False self._running = False @@ -146,7 +141,6 @@ def _reassemble_ligs(self): try: for gen in generators: - print("gen:", gen) for line in gen: str = lines.strip('\n') fout.write(''.join(str)) @@ -164,11 +158,9 @@ def _docking_finished(self): (results, errors) = self._smina_process.communicate() if len(errors) == 0: for line in results.decode().splitlines(): - print("result line:", line) nanome.util.Logs.debug(line) else: for line in errors.decode().splitlines(): - print("error line:", line) nanome.util.Logs.warning(line) except Exception as e: print(traceback.format_exc()) @@ -183,7 +175,6 @@ def _docking_finished(self): docked_ligands.molecular.name = "Docking" docked_ligands.rendering.visible = True - self._plugin.make_plugin_usable() if self._scoring: nanome.util.Logs.debug("Display scoring result") self._plugin.display_scoring_result(docked_ligands) diff --git a/nanome_docking/_DockingCalculationsAutodock4.py b/nanome_docking/_DockingCalculationsAutodock4.py index 49da38b..4179cf4 100644 --- a/nanome_docking/_DockingCalculationsAutodock4.py +++ b/nanome_docking/_DockingCalculationsAutodock4.py @@ -298,5 +298,6 @@ def _bonds_finished(self): docked_ligands.transform.rotation = self._receptor.transform.rotation nanome.util.Logs.debug("Update workspace") - self._plugin.make_plugin_usable() + # TODO: verify this shouldn't be here anymore (test) + # self._plugin.make_plugin_usable() self._plugin.add_result_to_workspace([docked_ligands]) \ No newline at end of file diff --git a/nanome_docking/_DockingCalculationsRhodium.py b/nanome_docking/_DockingCalculationsRhodium.py index 7756522..e7980aa 100644 --- a/nanome_docking/_DockingCalculationsRhodium.py +++ b/nanome_docking/_DockingCalculationsRhodium.py @@ -162,7 +162,8 @@ def bonds_added(complex_arr): # Docking process is over, clean files and make plugin available again self.clean_files(docking_output) - self._plugin.make_plugin_usable() + # TODO: Verify this shouldn't be here anymore (test) + # self._plugin.make_plugin_usable(True) self._plugin.send_notification(NotificationTypes.success, "Docking finished") # Add bonds to the result complex diff --git a/nanome_docking/_DockingMenu.py b/nanome_docking/_DockingMenu.py index 4c71733..107277d 100644 --- a/nanome_docking/_DockingMenu.py +++ b/nanome_docking/_DockingMenu.py @@ -50,7 +50,7 @@ def disable_autobox(self): self._plugin.update_menu(self._menu) def make_plugin_usable(self, state=True): - self._run_button.unusable = not state | self.refresh_run_btn_enabled(False) + self._run_button.unusable = (not state) | self.refresh_run_btn_unusable(False) self._plugin.update_content(self._run_button) def receptor_pressed(self, button): @@ -64,7 +64,7 @@ def receptor_pressed(self, button): self._receptor_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'checkmark.png') self._plugin.update_content(self._receptor_checkmark) - self.refresh_run_btn_enabled() + self.refresh_run_btn_unusable() def ligand_pressed(self, button): if button.selected == False: @@ -80,7 +80,7 @@ def ligand_pressed(self, button): self._ligand_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'none.png') self._plugin.update_content(self._ligand_checkmark) - self.refresh_run_btn_enabled() + self.refresh_run_btn_unusable() def site_pressed(self, button): lastSelected = self._selected_site @@ -93,9 +93,9 @@ def site_pressed(self, button): self._site_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'checkmark.png') self._plugin.update_content(self._site_checkmark) - self.refresh_run_btn_enabled() + self.refresh_run_btn_unusable() - def refresh_run_btn_enabled(self, update=True): + def refresh_run_btn_unusable(self, update=True): if self._selected_receptor != None and len(self._selected_ligands) > 0 and self._selected_site != None: self._run_button.text.value_unusable = "Running..." self._run_button.unusable = False @@ -117,13 +117,7 @@ def complex_pressed(button): elif self._tab.text.value_idle == "Site": self.site_pressed(button) - self._selected_receptor = None - self._selected_ligands = [] - self._selected_site = None - self._complex_list.items = [] - self._receptor_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'none.png') - self._ligand_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'none.png') - self._site_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'none.png') + self.reset(update_menu=False) for complex in complex_list: clone = self._complex_item_prefab.clone() @@ -137,7 +131,8 @@ def complex_pressed(button): self._plugin.update_menu(self._menu) def display_scoring_result(self, result): - self.reset_menu() + nanome.util.Logs.debug("resetting the menu...") + self.reset() for molecule in result.molecules: clone = self._score_item_prefab.clone() @@ -146,10 +141,14 @@ def display_scoring_result(self, result): lbl.text_value = molecule.name + " - " + molecule._associated["> "] self._score_list.items.append(clone) - def reset_menu(self): + def reset(self, update_menu=True): self._selected_receptor = None self._selected_ligands = [] - self._selected_site == None + self._selected_site = None + self._complex_list.items = [] + self._receptor_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'none.png') + self._ligand_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'none.png') + self._site_checkmark.file_path = os.path.join(os.path.dirname(__file__), 'none.png') self.make_plugin_usable() self._plugin.update_menu(self._menu) @@ -305,7 +304,7 @@ def scoring_button_pressed_callback(button): run_button.register_pressed_callback(run_button_pressed_callback) self._run_button = run_button self._run_button.enabled = False - self.refresh_run_btn_enabled() + self.refresh_run_btn_unusable() # lists self._complex_list = menu.root.find_node("ComplexList", True).get_content() From cd145a0db7e6c63d7601757675bc98b83475f321 Mon Sep 17 00:00:00 2001 From: Max Howard Date: Tue, 22 Oct 2019 17:24:38 -0700 Subject: [PATCH 16/19] cleanup + interaction label work --- nanome_docking/_DockingCalculations.py | 67 +++++++++++--------------- 1 file changed, 29 insertions(+), 38 deletions(-) diff --git a/nanome_docking/_DockingCalculations.py b/nanome_docking/_DockingCalculations.py index e59af56..572677c 100644 --- a/nanome_docking/_DockingCalculations.py +++ b/nanome_docking/_DockingCalculations.py @@ -1,5 +1,6 @@ import traceback - +import math +import re import nanome import shutil import gzip @@ -26,18 +27,6 @@ except: pass -def not_dollars(line): - return '$$$$' != line.strip('\n') - -def parse_molecules(file, self): - nanome.util.Logs.debug("Parsing output", file) - with open(file) as lines: - while True: - block = list(itertools.takewhile(not_dollars, lines )) - if not block: - break - yield block + ['$$$$\n'] - class DockingCalculations(): def __init__(self, plugin): self._plugin = plugin @@ -57,7 +46,6 @@ def initialize(self): self._ligand_output = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb", dir=self.temp_dir.name) self._log_file = tempfile.NamedTemporaryFile(delete=False, dir=self.temp_dir.name) - def start_docking(self, receptor, ligands, site, exhaustiveness, modes, align, replace, scoring, autobox): self._exhaustiveness = exhaustiveness self._modes = modes @@ -75,7 +63,6 @@ def start_docking(self, receptor, ligands, site, exhaustiveness, modes, align, r self._started_docking = False self._request_pending = True - def update(self): if self._request_pending == False: return @@ -95,7 +82,7 @@ def write_structures_to_file(self): self._receptor.io.to_pdb(self._receptor_input.name, PDBOPTIONS) nanome.util.Logs.debug("Saved PDB", self._receptor_input.name) self._ligands.io.to_pdb(self._ligands_input.name, PDBOPTIONS) - nanome.util.Logs.debug("Saved SDF", self._ligands_input.name) + nanome.util.Logs.debug("Saved PDB", self._ligands_input.name) self._site.io.to_pdb(self._site_input.name, PDBOPTIONS) nanome.util.Logs.debug("Saved SDF", self._site_input.name) @@ -116,7 +103,8 @@ def _start_docking(self): else: smina_args = [exe_path, '-r', self._receptor_input.name, '-l', self._ligands_input.name, '--autobox_ligand', self._site_input.name, '--out', \ - self._docking_output.name, '--log', self._log_file.name, '--exhaustiveness', str(self._exhaustiveness), '--num_modes', str(self._modes), '--autobox_add', str(self._autobox), '--seed', '0'] + self._docking_output.name, '--log', self._log_file.name, '--exhaustiveness', str(self._exhaustiveness), '--num_modes', str(self._modes), '--autobox_add', str(self._autobox), '--atom_term_data'] + nanome.util.Logs.debug("Run SMINA") self._start_timer = timer() try: @@ -134,21 +122,6 @@ def _start_docking(self): def _check_docking(self): return self._smina_process.poll() != None - - def _reassemble_ligs(self): - generators = parse_molecules(self._docking_output.name, self) - fout = open(self._ligand_output.name, 'w') - - try: - for gen in generators: - for line in gen: - str = lines.strip('\n') - fout.write(''.join(str)) - fout.write('\n') - except StopIteration: - pass - - fout.close() def _docking_finished(self): end = timer() @@ -157,7 +130,7 @@ def _docking_finished(self): try: (results, errors) = self._smina_process.communicate() if len(errors) == 0: - for line in results.decode().splitlines(): + for index,line in enumerate(results.decode().splitlines()): nanome.util.Logs.debug(line) else: for line in errors.decode().splitlines(): @@ -165,15 +138,17 @@ def _docking_finished(self): except Exception as e: print(traceback.format_exc()) - if not self._scoring: - pass - # self._reassemble_ligs() docked_ligands = nanome.structure.Complex.io.from_sdf(path=self._docking_output.name) nanome.util.Logs.debug("Read PDB", self._docking_output.name) + for line in open(self._docking_output.name): + print(line) + for i, molecule in enumerate(docked_ligands.molecules): + nanome.util.Logs.debug("molecule " + str(i)) + self.apply_interaction_labels(molecule) if not self._scoring: - docked_ligands.molecular.name = "Docking" - docked_ligands.rendering.visible = True + docked_ligands.name = "Docking" + docked_ligands.visible = True if self._scoring: nanome.util.Logs.debug("Display scoring result") @@ -185,3 +160,19 @@ def _docking_finished(self): shutil.rmtree(self.temp_dir.name) self._plugin.send_notification(NotificationTypes.success, "Docking finished") + + def apply_interaction_labels(self, molecule): + num_rgx = '(-?(?:\d+)?\.?\d+)' + pattern = re.compile('\<{},{},{}\> {} {} {} {} {}'.format(*([num_rgx] * 8)), re.U) + for associated in molecule.associateds: + interaction_terms = associated['> '] + interaction_values = re.findall(pattern, interaction_terms) + atom_count = len([atom for atom in molecule.atoms]) + print("atom count ({}) == interaction_value count ({})".format(atom_count, len(interaction_values))) + for i, atom in enumerate(molecule.atoms): + if i < len(interaction_values) - 1: + atom.position + nanome.util.Logs.debug("interaction values for atom " + str(i) + ": "+ str(interaction_values[i])) + atom.label_text = str(interaction_values[i][5]) + atom.labeled = True + nanome.util.Logs.debug("atom " + str(i) + " interaction term: " + atom.label_text) \ No newline at end of file From 6ca89eb4de12963c921b856bccec853377caa9a0 Mon Sep 17 00:00:00 2001 From: Max Howard Date: Mon, 4 Nov 2019 12:19:03 -0800 Subject: [PATCH 17/19] cleaned up, visual scoring working --- nanome_docking/Docking.py | 71 ++++++++---- nanome_docking/_DockingCalculations.py | 104 ++++++++++++------ .../_DockingCalculationsAutodock4.py | 3 +- nanome_docking/_DockingMenu.py | 31 +++++- nanome_docking/_docking_menu.json | 2 +- 5 files changed, 149 insertions(+), 62 deletions(-) diff --git a/nanome_docking/Docking.py b/nanome_docking/Docking.py index fe8943d..6317611 100644 --- a/nanome_docking/Docking.py +++ b/nanome_docking/Docking.py @@ -4,6 +4,7 @@ from ._DockingCalculationsRhodium import DockingCalculations as Rhodium from ._DockingMenu import DockingMenu from ._DockingMenuRhodium import DockingMenuRhodium +import functools import sys __metaclass__ = type @@ -67,42 +68,72 @@ def make_plugin_usable(self): def on_complex_list_received(self, complexes): self._menu.change_complex_list(complexes) - def run_docking(self, receptor, ligands, site, params): - # Change the plugin to be "unusable" - if self._menu._run_button.unusable == True: - return - self._menu.make_plugin_usable(False) - - has_site = site != None - - def on_complexes_received(complexes): + def combine_ligands_start_docking(self, receptor, site, params, individual_ligands): + combined_ligands = nanome.structure.Complex() + combined_ligands.names = [] + print("ligands:", individual_ligands) + for ligand in individual_ligands: + convert_atoms_to_absolute_position(ligand) + convert_atoms_to_relative_position(ligand, receptor.m_workspace_to_complex) + combined_ligands.names.append(ligand.name) + for molecule in ligand.molecules: + combined_ligands.add_molecule(molecule) + self._calculations.start_docking(receptor, combined_ligands, site, **params) + + def replace_conformer(self, complexes, callback, existing=True): + for i in range(len(complexes)): + complex_index = complexes[i].index + complexes[i] = complexes[i].convert_to_frames() + complexes[i].index = complex_index + # send frame-based complexes to nanome, request them back + # complex_indices = + + rerequest_complexes = functools.partial(self.request_complexes, [complex.index for complex in complexes], callback) + + request_docking_results = functools.partial(self.request_docking_results, callback) + rerequest_complexes = functools.partial(self.request_complex_list, request_docking_results) if not existing else rerequest_complexes + + self.update_structures_deep(complexes, rerequest_complexes) + + def request_docking_results(self, callback, all_complexes): + docking_results_index = all_complexes[len(all_complexes)-1].index + print("docking results id:", docking_results_index) + self.request_complexes([docking_results_index], callback) + + def set_and_convert_structures(self, has_site, params, complexes): # When deep complexes data are received, unpack them and prepare ligand for docking receptor = complexes[0] + receptor.m_workspace_to_complex = receptor.get_workspace_to_complex_matrix() self._receptor = receptor # convert_atoms_to_absolute_position(receptor) - m_workspace_to_receptor = receptor.get_workspace_to_complex_matrix() starting_lig_idx = 1 site = None if has_site: site = complexes[1] self._site = site convert_atoms_to_absolute_position(site) - convert_atoms_to_relative_position(site, m_workspace_to_receptor) + convert_atoms_to_relative_position(site, receptor.m_workspace_to_complex) starting_lig_idx = 2 - ligands = nanome.structure.Complex() - for ligand in complexes[starting_lig_idx:]: - convert_atoms_to_absolute_position(ligand) - convert_atoms_to_relative_position(ligand, m_workspace_to_receptor) - for molecule in ligand.molecules: - ligands.add_molecule(molecule) - self._calculations.start_docking(receptor, ligands, site, **params) + # convert ligands to frame representation + ligands = complexes[starting_lig_idx:] + combine_ligs_and_start_docking = functools.partial(self.combine_ligands_start_docking, receptor, site, params) + self.replace_conformer(ligands, combine_ligs_and_start_docking) + + def run_docking(self, receptor, ligands, site, params): + print("params:", str(params)) + # Change the plugin to be "unusable" + if self._menu._run_button.unusable == True: + return + self._menu.make_plugin_usable(False) # Request complexes to Nanome in this order: [receptor, site (if any), ligand, ligand,...] request_list = [receptor.index] - if has_site: + if site != None: request_list.append(site.index) request_list += [x.index for x in ligands] - self.request_complexes(request_list, on_complexes_received) + + setup_structures = functools.partial(self.set_and_convert_structures, site != None, params) + self.request_complexes(request_list, setup_structures) # Called every update tick of the Plugin def update(self): diff --git a/nanome_docking/_DockingCalculations.py b/nanome_docking/_DockingCalculations.py index 572677c..83cc7e6 100644 --- a/nanome_docking/_DockingCalculations.py +++ b/nanome_docking/_DockingCalculations.py @@ -40,13 +40,12 @@ def initialize(self): self.temp_dir = tempfile.TemporaryDirectory() self._receptor_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb", dir=self.temp_dir.name) self._ligands_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb", dir=self.temp_dir.name) - self._ligands_pdb_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb", dir=self.temp_dir.name) self._site_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb", dir=self.temp_dir.name) self._docking_output = tempfile.NamedTemporaryFile(delete=False, prefix="output", suffix=".sdf", dir=self.temp_dir.name) self._ligand_output = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb", dir=self.temp_dir.name) self._log_file = tempfile.NamedTemporaryFile(delete=False, dir=self.temp_dir.name) - def start_docking(self, receptor, ligands, site, exhaustiveness, modes, align, replace, scoring, autobox): + def start_docking(self, receptor, ligands, site, exhaustiveness, modes, align, replace, scoring, visual_scores, autobox): self._exhaustiveness = exhaustiveness self._modes = modes self._receptor = receptor @@ -55,6 +54,7 @@ def start_docking(self, receptor, ligands, site, exhaustiveness, modes, align, r self._align = align self._replace = replace self._scoring = scoring + self._visual_scores = visual_scores self._autobox = autobox # Start docking process @@ -84,7 +84,7 @@ def write_structures_to_file(self): self._ligands.io.to_pdb(self._ligands_input.name, PDBOPTIONS) nanome.util.Logs.debug("Saved PDB", self._ligands_input.name) self._site.io.to_pdb(self._site_input.name, PDBOPTIONS) - nanome.util.Logs.debug("Saved SDF", self._site_input.name) + nanome.util.Logs.debug("Saved PDB", self._site_input.name) def _check_conversion(self): poll = self._obabel_process.poll() @@ -122,57 +122,89 @@ def _start_docking(self): def _check_docking(self): return self._smina_process.poll() != None - - def _docking_finished(self): - end = timer() - nanome.util.Logs.debug("Docking Finished in", end - self._start_timer, "seconds") - self._request_pending = False - try: - (results, errors) = self._smina_process.communicate() - if len(errors) == 0: - for index,line in enumerate(results.decode().splitlines()): - nanome.util.Logs.debug(line) - else: - for line in errors.decode().splitlines(): - nanome.util.Logs.warning(line) - except Exception as e: - print(traceback.format_exc()) - - docked_ligands = nanome.structure.Complex.io.from_sdf(path=self._docking_output.name) - nanome.util.Logs.debug("Read PDB", self._docking_output.name) - for line in open(self._docking_output.name): - print(line) - for i, molecule in enumerate(docked_ligands.molecules): + + def _resume_docking_finished(self, docking_results): + docking_results = docking_results[0] + print("docking results:", [molecule for molecule in docking_results.molecules]) + nanome.util.Logs.debug("Read SDF", self._docking_output.name) + for i, molecule in enumerate(docking_results.molecules): nanome.util.Logs.debug("molecule " + str(i)) - self.apply_interaction_labels(molecule) + self.set_scores(i, molecule) + + if self._visual_scores: + self.visualize_scores(docking_results) if not self._scoring: - docked_ligands.name = "Docking" - docked_ligands.visible = True + if len(self._ligands.names) > 1: + docking_results.name += "Docking Results" + elif len(self._ligands.names) == 1: + docking_results.name = self._ligands.names[0] + " (Docked)" + docking_results.visible = True if self._scoring: nanome.util.Logs.debug("Display scoring result") - self._plugin.display_scoring_result(docked_ligands) + self._plugin.display_scoring_result(docking_results) else: nanome.util.Logs.debug("Update workspace") - self._plugin.add_result_to_workspace([docked_ligands], self._align) + self._plugin.add_result_to_workspace([docking_results], self._align) shutil.rmtree(self.temp_dir.name) self._plugin.send_notification(NotificationTypes.success, "Docking finished") + + def _docking_finished(self): + end = timer() + nanome.util.Logs.debug("Docking Finished in", end - self._start_timer, "seconds") + self._request_pending = False + + docking_results = nanome.structure.Complex.io.from_sdf(path=self._docking_output.name) + docking_results.index = 0 + print("docked_ligand molecules:", [molecule for molecule in docking_results.molecules]) + self._plugin.replace_conformer([docking_results], self._resume_docking_finished, existing=False) + + def update_min_max_scores(self, molecule, score): + min_score = molecule.min_atom_score + max_score = molecule.max_atom_score + molecule.min_atom_score = score if score < min_score else min_score + molecule.max_atom_score = score if score > max_score else max_score - def apply_interaction_labels(self, molecule): - num_rgx = '(-?(?:\d+)?\.?\d+)' - pattern = re.compile('\<{},{},{}\> {} {} {} {} {}'.format(*([num_rgx] * 8)), re.U) + def set_scores(self, lig_i, molecule): + molecule.min_atom_score = float('inf') + molecule.max_atom_score = float('-inf') + + num_rgx = '(-?[\d.]+(?:e[+-]\d+)?)' + pattern = re.compile('<{},{},{}> {} {} {} {} {}'.format(*([num_rgx] * 8)), re.U) for associated in molecule.associateds: + pose_score = associated['> '] + for residue in molecule.residues: + print("pose score:", pose_score) + residue.label_text = pose_score + " kcal/mol" + residue.labeled = True interaction_terms = associated['> '] interaction_values = re.findall(pattern, interaction_terms) atom_count = len([atom for atom in molecule.atoms]) - print("atom count ({}) == interaction_value count ({})".format(atom_count, len(interaction_values))) for i, atom in enumerate(molecule.atoms): if i < len(interaction_values) - 1: - atom.position nanome.util.Logs.debug("interaction values for atom " + str(i) + ": "+ str(interaction_values[i])) - atom.label_text = str(interaction_values[i][5]) + atom.score = float(interaction_values[i][5]) + self.update_min_max_scores(molecule, atom.score) + + + def visualize_scores(self, ligand_complex): + for molecule in ligand_complex.molecules: + for atom in molecule.atoms: + if hasattr(atom, "score"): + atom.atom_mode = nanome.api.structure.Atom.AtomRenderingMode.Point + denominator = -molecule.min_atom_score if atom.score < 0 else molecule.max_atom_score + norm_score = atom.score / denominator + atom.atom_scale = norm_score * 1.5 + 0.1 + atom.label_text = self.truncate(atom.score, 3) atom.labeled = True - nanome.util.Logs.debug("atom " + str(i) + " interaction term: " + atom.label_text) \ No newline at end of file + + def truncate(self, f, n): + '''Truncates/pads a float f to n decimal places without rounding''' + s = '{}'.format(f) + if 'e' in s or 'E' in s: + return '{0:.{1}f}'.format(f, n) + i, p, d = s.partition('.') + return '.'.join([i, (d+'0'*n)[:n]]) \ No newline at end of file diff --git a/nanome_docking/_DockingCalculationsAutodock4.py b/nanome_docking/_DockingCalculationsAutodock4.py index 4179cf4..ca3d7ad 100644 --- a/nanome_docking/_DockingCalculationsAutodock4.py +++ b/nanome_docking/_DockingCalculationsAutodock4.py @@ -35,7 +35,7 @@ def initialize(self): self._autogrid_log = tempfile.NamedTemporaryFile(delete=False, suffix=".glg") self._autodock_log = tempfile.NamedTemporaryFile(delete=False, suffix=".dlf") - def start_docking(self, receptor, ligands, site, exhaustiveness, modes, align, replace, scoring, autobox): + def start_docking(self, receptor, ligands, site, exhaustiveness, modes, align, replace, scoring, visual_scores, autobox): self.initialize() # Save all input files receptor.io.to_pdb(self._protein_input.name, self._pdb_options) @@ -47,6 +47,7 @@ def start_docking(self, receptor, ligands, site, exhaustiveness, modes, align, r self._site = site self._align = align self._replace = replace + self._display_scoring = display_scoring # Start docking process self._running = False diff --git a/nanome_docking/_DockingMenu.py b/nanome_docking/_DockingMenu.py index 107277d..88a9fb7 100644 --- a/nanome_docking/_DockingMenu.py +++ b/nanome_docking/_DockingMenu.py @@ -9,19 +9,34 @@ def __init__(self, docking_plugin): self._selected_receptor = None self._selected_ligands = [] self._selected_site = None - self._exhaustiveness = 8 - self._modes = 9 + self._exhaustiveness = 10 + self._modes = 5 self._autobox = 4 self._run_button = None self._run_button = None self._align = True self._replace = False self._scoring = False + self._visual_scores = False self._tab = None self._autobox_enabled = True - + + def get_receptor(self): + return self._selected_receptor.complex + + def get_ligands(self): + ligands = [] + for item in self._selected_ligands: + ligands.append(item.complex) + return ligands + + def get_site(self): + if self._selected_site == None: + return None + return self._selected_site.complex + def get_params(self): - params = {"exhaustiveness": None, "modes": None, "align": None, "replace": None, "scoring": None, "autobox": None} + params = {"exhaustiveness": None, "modes": None, "align": None, "replace": None, "scoring": None, "visual_scores": None, "autobox": None} for key, value in params.items(): newvalue = getattr(self, "_"+key) params[key] = newvalue @@ -237,6 +252,11 @@ def scoring_button_pressed_callback(button): button.selected = self._scoring self._plugin.update_content(button) + def visual_scores_button_pressed_callback(button): + self._visual_scores = not self._visual_scores + button.selected = self._visual_scores + self._plugin.update_content(button) + # Create a prefab that will be used to populate the lists self._complex_item_prefab = nanome.ui.LayoutNode() self._complex_item_prefab.layout_orientation = nanome.ui.LayoutNode.LayoutTypes.horizontal @@ -297,6 +317,9 @@ def scoring_button_pressed_callback(button): self._score_btn = menu.root.find_node("ScoringButton", True).get_content() self._score_btn.register_pressed_callback(scoring_button_pressed_callback) + self._display_score_btn = menu.root.find_node("VisualScoresButton", True).get_content() + self._display_score_btn.register_pressed_callback(visual_scores_button_pressed_callback) + close_score_btn = menu.root.find_node("CloseScoreButton", True).get_content() close_score_btn.register_pressed_callback(close_score_pressed_callback) diff --git a/nanome_docking/_docking_menu.json b/nanome_docking/_docking_menu.json index f47aeb9..bd8feec 100644 --- a/nanome_docking/_docking_menu.json +++ b/nanome_docking/_docking_menu.json @@ -1 +1 @@ -{"title": "Docking", "version": 0, "width": 0.829999983310699, "height": 0.600000023841858, "is_menu": true, "effective_root": {"name": "Root", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 1, "forward_dist": 0, "padding_type": 1, "padding_x": -1, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "", "text_vertical_align": 1, "text_horizontal_align": 1, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": [{"name": "LeftSideScore", "enabled": false, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "ScoreList", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 5, "forward_dist": 0.01, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"display_columns": 1, "display_rows": 6, "total_columns": 1, "unusable": false, "type_name": "List"}, "children": []}, {"name": "CloseScoreButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.0179999992251396, "padding_z": 0.0149999996647239, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "--", "text_value_selected": "--", "text_value_highlighted": "--", "text_value_selected_highlighted": "--", "text_value_unusable": "--", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "LeftSide", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Top", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 2, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "RecepeterData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "ReceptorIcon", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "ReceptorText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Receptor:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}, {"name": "LigandData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "LigandIcon", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "LigandText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Ligand:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}, {"name": "SiteData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "SiteIcon", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "SiteText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Site:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}]}, {"name": "Bot", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 4, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Tabs", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.270000010728836, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Receptor", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "ReceptorButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Receptor", "text_value_selected": "Receptor", "text_value_highlighted": "Receptor", "text_value_selected_highlighted": "Receptor", "text_value_unusable": "Receptor", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.280000001192093, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Ligand", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "LigandButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Ligand", "text_value_selected": "Ligand", "text_value_highlighted": "Ligand", "text_value_selected_highlighted": "Ligand", "text_value_unusable": "Ligand", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Site", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "SiteButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Site", "text_value_selected": "Site", "text_value_highlighted": "Site", "text_value_selected_highlighted": "Site", "text_value_unusable": "Site", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}]}, {"name": "List", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0.01, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Mesh", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"mesh_color": 691685119, "type_name": "Mesh"}, "children": []}, {"name": "ComplexList", "enabled": true, "layer": 1, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0.01, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"display_columns": 1, "display_rows": 3, "total_columns": 1, "unusable": false, "type_name": "List"}, "children": []}]}]}]}, {"name": "RightSide", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.75, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Exhaustiveness", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Exhaust.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "ExhaustivenessInput", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 10, "placeholder_text": "10", "input_text": "10", "type_name": "Text Input"}, "children": []}]}, {"name": "NumModes", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Num Modes", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "ModesInput", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 5, "placeholder_text": "5", "input_text": "5", "type_name": "Text Input"}, "children": []}]}, {"name": "Autobox", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Autobox", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "AutoboxInput", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 4, "placeholder_text": "4", "input_text": "4", "type_name": "Text Input"}, "children": []}]}, {"name": "AlignAfter", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Align After", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "AlignButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "off", "text_value_selected": "on", "text_value_highlighted": "off", "text_value_selected_highlighted": "on", "text_value_unusable": "off", "text_auto_size": true, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "ScoringOnly", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Scoring Only", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.330000013113022, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "ScoringButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "off", "text_value_selected": "on", "text_value_highlighted": "off", "text_value_selected_highlighted": "on", "text_value_unusable": "off", "text_auto_size": true, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Run", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "RunButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Run", "text_value_selected": "Run", "text_value_highlighted": "Run", "text_value_selected_highlighted": "Run", "text_value_unusable": "Running...", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.430000007152557, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}]}]}} \ No newline at end of file +{"title": "Docking", "version": 0, "width": 0.829999983310699, "height": 0.600000023841858, "is_menu": true, "effective_root": {"name": "Root", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 1, "forward_dist": 0, "padding_type": 1, "padding_x": -1, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "", "text_vertical_align": 1, "text_horizontal_align": 1, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": [{"name": "LeftSideScore", "enabled": false, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "ScoreList", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 5, "forward_dist": 0.00999999977648258, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"display_columns": 1, "display_rows": 6, "total_columns": 1, "unusable": false, "type_name": "List"}, "children": []}, {"name": "CloseScoreButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.0179999992251396, "padding_z": 0.0149999996647239, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "--", "text_value_selected": "--", "text_value_highlighted": "--", "text_value_selected_highlighted": "--", "text_value_unusable": "--", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "LeftSide", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Top", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 2, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "RecepeterData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "ReceptorIcon", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "ReceptorText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Receptor:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}, {"name": "LigandData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "LigandIcon", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "LigandText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Ligand:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}, {"name": "SiteData", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "SiteIcon", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.119999997317791, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0.00999999977648258, "padding_z": 0.00999999977648258, "padding_w": 0.00999999977648258, "content": null, "children": []}, {"name": "SiteText", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Site:", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}]}]}, {"name": "Bot", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 4, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Tabs", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.270000010728836, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Receptor", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "ReceptorButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Receptor", "text_value_selected": "Receptor", "text_value_highlighted": "Receptor", "text_value_selected_highlighted": "Receptor", "text_value_unusable": "Receptor", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.280000001192093, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Ligand", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "LigandButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Ligand", "text_value_selected": "Ligand", "text_value_highlighted": "Ligand", "text_value_selected_highlighted": "Ligand", "text_value_unusable": "Ligand", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Site", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "SiteButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Site", "text_value_selected": "Site", "text_value_highlighted": "Site", "text_value_selected_highlighted": "Site", "text_value_unusable": "Site", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.300000011920929, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}]}, {"name": "List", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0.00999999977648258, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Mesh", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"mesh_color": 691685119, "type_name": "Mesh"}, "children": []}, {"name": "ComplexList", "enabled": true, "layer": 1, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0.00999999977648258, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"display_columns": 1, "display_rows": 3, "total_columns": 1, "unusable": false, "type_name": "List"}, "children": []}]}]}]}, {"name": "RightSide", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.75, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Exhaustiveness", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Exhaust.", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "ExhaustivenessInput", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 10, "placeholder_text": "10", "input_text": "10", "type_name": "Text Input"}, "children": []}]}, {"name": "NumModes", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Num Modes", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "ModesInput", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 5, "placeholder_text": "5", "input_text": "5", "type_name": "Text Input"}, "children": []}]}, {"name": "Autobox", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Autobox", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "AutoboxInput", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"max_length": 4, "placeholder_text": "4", "input_text": "4", "type_name": "Text Input"}, "children": []}]}, {"name": "AlignAfter", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Align After", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.349999994039536, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "AlignButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "off", "text_value_selected": "on", "text_value_highlighted": "off", "text_value_selected_highlighted": "on", "text_value_unusable": "off", "text_auto_size": true, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "ScoringOnly", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "Text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Scoring Only", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.330000013113022, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "ScoringButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "off", "text_value_selected": "on", "text_value_highlighted": "off", "text_value_selected_highlighted": "on", "text_value_unusable": "off", "text_auto_size": true, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Scoring Labels", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "text", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": {"text": "Visual Scores", "text_vertical_align": 1, "text_horizontal_align": 0, "text_auto_size": true, "text_min_size": 0, "text_max_size": 72, "text_size": 0.28999999165535, "text_color": -1, "text_bold": true, "text_italics": false, "text_underlined": false, "type_name": "Label"}, "children": []}, {"name": "VisualScoresButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 2, "sizing_value": 0.400000005960464, "forward_dist": 0.0020000000949949, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0.0149999996647239, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "off", "text_value_selected": "on", "text_value_highlighted": "off", "text_value_selected_highlighted": "on", "text_value_unusable": "off", "text_auto_size": true, "text_min_size": 0, "text_max_size": 72, "text_size": 1, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}, {"name": "Run", "enabled": true, "layer": 0, "layout_orientation": 1, "sizing_type": 2, "sizing_value": 1, "forward_dist": 0, "padding_type": 0, "padding_x": 0, "padding_y": 0, "padding_z": 0, "padding_w": 0, "content": null, "children": [{"name": "RunButton", "enabled": true, "layer": 0, "layout_orientation": 0, "sizing_type": 0, "sizing_value": 0, "forward_dist": 0, "padding_type": 0, "padding_x": 0.0179999992251396, "padding_y": 0, "padding_z": 0.0149999996647239, "padding_w": 0, "content": {"selected": false, "unusable": false, "text_active": true, "text_value_idle": "Run", "text_value_selected": "Run", "text_value_highlighted": "Run", "text_value_selected_highlighted": "Run", "text_value_unusable": "Running...", "text_auto_size": false, "text_min_size": 0, "text_max_size": 72, "text_size": 0.430000007152557, "text_underlined": false, "text_bolded": true, "text_vertical_align": 1, "text_horizontal_align": 1, "type_name": "Button"}, "children": []}]}]}]}} \ No newline at end of file From dd61900369fa606515ae99eaf1d55e534cd8a5c8 Mon Sep 17 00:00:00 2001 From: Max Howard Date: Tue, 5 Nov 2019 16:58:38 -0800 Subject: [PATCH 18/19] hop --- README.md | 3 +- nanome_docking/_DockingCalculations.py | 1 + .../_DockingCalculationsAutodock4.py | 67 +++++++++---------- nanome_docking/_DockingCalculationsRhodium.py | 1 + nanome_docking/_DockingMenu.py | 8 ++- publish.sh | 0 setup.py | 7 +- 7 files changed, 47 insertions(+), 40 deletions(-) mode change 100644 => 100755 publish.sh diff --git a/README.md b/README.md index 2628f18..a958dc9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Nanome - Docking -Plugin to dock ligands to a receptor and display the result in Nanome +This Nanome plugin interfaces with a variety of docking softwares to dock ligands to a receptor and display the result in Nanome. ### Installation @@ -33,6 +33,7 @@ In Nanome: - Click on "Ligand", and select ligands to dock - If using Smina, click on "Site", and select which molecule should be used to define the docking site - Choose exhaustiveness, number of results and size of the box to generate around the site molecule (Smina only) +- If visual scoring is turned on, atom size and labels will indicate each atom's contribution to the ligand's score - Click on Run ### License diff --git a/nanome_docking/_DockingCalculations.py b/nanome_docking/_DockingCalculations.py index 83cc7e6..f03668a 100644 --- a/nanome_docking/_DockingCalculations.py +++ b/nanome_docking/_DockingCalculations.py @@ -34,6 +34,7 @@ def __init__(self, plugin): self._running = False self._structures_written = False self._started_docking = False + self.requires_site = True def initialize(self): diff --git a/nanome_docking/_DockingCalculationsAutodock4.py b/nanome_docking/_DockingCalculationsAutodock4.py index ca3d7ad..790295f 100644 --- a/nanome_docking/_DockingCalculationsAutodock4.py +++ b/nanome_docking/_DockingCalculationsAutodock4.py @@ -1,5 +1,6 @@ import nanome import os +import shutil import subprocess import tempfile import re @@ -21,19 +22,21 @@ def __init__(self, plugin): self._pdb_options.write_bonds = True self._sdf_options = SDFOptions() self._sdf_options.write_bonds = True + self.requires_site = False def initialize(self): # TODO: Read and write in a folder unique per plugin instance - self._protein_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb") - self._protein_input_converted = tempfile.NamedTemporaryFile(delete=False, suffix=".pdbqt") - self._ligands_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb") - self._ligands_input_converted = tempfile.NamedTemporaryFile(delete=False, suffix=".pdbqt") - self._ligands_output = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb") - self._bond_output = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf") - self._autogrid_input = tempfile.NamedTemporaryFile(delete=False, suffix=".gpf") - self._autodock_input = tempfile.NamedTemporaryFile(delete=False, suffix=".dpf") - self._autogrid_log = tempfile.NamedTemporaryFile(delete=False, suffix=".glg") - self._autodock_log = tempfile.NamedTemporaryFile(delete=False, suffix=".dlf") + self.temp_dir = tempfile.TemporaryDirectory() + self._protein_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb", dir=self.temp_dir.name) + self._protein_input_converted = tempfile.NamedTemporaryFile(delete=False, suffix=".pdbqt", dir=self.temp_dir.name) + self._ligands_input = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb", dir=self.temp_dir.name) + self._ligands_input_converted = tempfile.NamedTemporaryFile(delete=False, suffix=".pdbqt", dir=self.temp_dir.name) + self._ligands_output = tempfile.NamedTemporaryFile(delete=False, suffix=".pdb", dir=self.temp_dir.name) + self._bond_output = tempfile.NamedTemporaryFile(delete=False, suffix=".sdf", dir=self.temp_dir.name) + self._autogrid_input = tempfile.NamedTemporaryFile(delete=False, suffix=".gpf", dir=self.temp_dir.name) + self._autodock_input = tempfile.NamedTemporaryFile(delete=False, suffix=".dpf", dir=self.temp_dir.name) + self._autogrid_log = tempfile.NamedTemporaryFile(delete=False, suffix=".glg", dir=self.temp_dir.name) + self._autodock_log = tempfile.NamedTemporaryFile(delete=False, suffix=".dlf", dir=self.temp_dir.name) def start_docking(self, receptor, ligands, site, exhaustiveness, modes, align, replace, scoring, visual_scores, autobox): self.initialize() @@ -44,10 +47,11 @@ def start_docking(self, receptor, ligands, site, exhaustiveness, modes, align, r nanome.util.Logs.debug("Saved PDB", self._ligands_input.name) self._receptor = receptor + self._ligands = ligands self._site = site self._align = align self._replace = replace - self._display_scoring = display_scoring + self._visual_scores = visual_scores # Start docking process self._running = False @@ -124,13 +128,13 @@ def _check_process_error(self, process, check_only_errors = False): def _start_preparation(self): # Awful situation here - lig_args = ['py', '-2.5', os.path.join(os.path.dirname(__file__), 'prepare_ligand4.py'), '-l', self._ligands_input.name, '-o', self._ligands_input_converted.name] - rec_args = ['py', '-2.5', os.path.join(os.path.dirname(__file__), 'prepare_receptor4.py'), '-r', self._protein_input.name, '-o', self._protein_input_converted.name] + lig_args = ['python', os.path.join(os.path.dirname(__file__), 'prepare_ligand4.py'), '-l', self._ligands_input.name, '-o', self._ligands_input_converted.name] + rec_args = ['python', os.path.join(os.path.dirname(__file__), 'prepare_receptor4.py'), '-r', self._protein_input.name, '-o', self._protein_input_converted.name] nanome.util.Logs.debug("Prepare ligand and receptor") self._start_timer = timer() - self._lig_process = subprocess.Popen(lig_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - self._rec_process = subprocess.Popen(rec_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + self._lig_process = subprocess.Popen(lig_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.temp_dir.name) + self._rec_process = subprocess.Popen(rec_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.temp_dir.name) self._running = True def _check_preparation(self): @@ -151,13 +155,14 @@ def _preparation_finished(self): def _start_parameters_preparation(self): # Awful situation here - grid_args = ['py', '-2.5', os.path.join(os.path.dirname(__file__), 'prepare_gpf4.py'), '-l', self._ligands_input_converted.name, '-r', self._protein_input_converted.name, '-o', self._autogrid_input.name] - dock_args = ['py', '-2.5', os.path.join(os.path.dirname(__file__), 'prepare_dpf42.py'), '-l', self._ligands_input_converted.name, '-r', self._protein_input_converted.name, '-o', self._autodock_input.name] + print("protein input converted name:", self._protein_input_converted.name) + grid_args = ['python', os.path.join(os.path.dirname(__file__), 'prepare_gpf4.py'), '-l', self._ligands_input_converted.name, '-r', self._protein_input_converted.name, '-o', self._autogrid_input.name] + dock_args = ['python', os.path.join(os.path.dirname(__file__), 'prepare_dpf42.py'), '-l', self._ligands_input_converted.name, '-r', self._protein_input_converted.name, '-o', self._autodock_input.name] nanome.util.Logs.debug("Prepare grid and docking parameter files") self._start_timer = timer() - self._grid_process = subprocess.Popen(grid_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - self._dock_process = subprocess.Popen(dock_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + self._grid_process = subprocess.Popen(grid_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.temp_dir.name) + self._dock_process = subprocess.Popen(dock_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.temp_dir.name) self._running = True def _check_parameters_preparation(self): @@ -182,15 +187,10 @@ def _parameters_preparation_finished(self): def _start_grid(self): full_name = self._autogrid_input.name - delimiter = full_name.rfind('\\') - path = full_name[:delimiter] - name = full_name[delimiter + 1:] - full_name_log = self._autogrid_log.name - delimiter_log = full_name_log.rfind('\\') - name_log = full_name_log[delimiter_log + 1:] + path = os.path.dirname(full_name) - args = ['autogrid4', '-p', name, '-l', name_log] + args = ['autogrid4', '-p', full_name, '-l', full_name_log] nanome.util.Logs.debug("Start Autogrid") self._start_timer = timer() @@ -215,15 +215,10 @@ def _grid_finished(self): def _start_docking(self): full_name_input = self._autodock_input.name - delimiter_input = full_name_input.rfind('\\') - path = full_name_input[:delimiter_input] - name_input = full_name_input[delimiter_input + 1:] - + path = os.path.dirname(full_name_input) full_name_log = self._autodock_log.name - delimiter_log = full_name_log.rfind('\\') - name_log = full_name_log[delimiter_log + 1:] - args = ['autodock4', '-p', name_input, '-l', name_log] + args = ['autodock4', '-p', full_name_input, '-l', full_name_log] nanome.util.Logs.debug("Start Autodock") self._start_timer = timer() @@ -292,7 +287,7 @@ def _bonds_finished(self): docked_ligands = nanome.structure.Complex.io.from_sdf(path=self._bond_output.name) nanome.util.Logs.debug("Read SDF", self._bond_output.name) - docked_ligands.name = "Docking" + docked_ligands.name = self._ligands[0].full_name + " (Docked)" docked_ligands.visible = True if self._align == True: docked_ligands.transform.position = self._receptor.transform.position @@ -301,4 +296,6 @@ def _bonds_finished(self): nanome.util.Logs.debug("Update workspace") # TODO: verify this shouldn't be here anymore (test) # self._plugin.make_plugin_usable() - self._plugin.add_result_to_workspace([docked_ligands]) \ No newline at end of file + self._plugin.add_result_to_workspace([docked_ligands]) + + shutil.rmtree(self.temp_dir.name) \ No newline at end of file diff --git a/nanome_docking/_DockingCalculationsRhodium.py b/nanome_docking/_DockingCalculationsRhodium.py index e7980aa..b015dd0 100644 --- a/nanome_docking/_DockingCalculationsRhodium.py +++ b/nanome_docking/_DockingCalculationsRhodium.py @@ -14,6 +14,7 @@ class DockingCalculations(): def __init__(self, plugin): self._plugin = plugin self.__docking_running = False + self.requires_site = False # Entry point, where everything starts def start_docking(self, receptor, ligands, site, params): diff --git a/nanome_docking/_DockingMenu.py b/nanome_docking/_DockingMenu.py index 88a9fb7..18aac9f 100644 --- a/nanome_docking/_DockingMenu.py +++ b/nanome_docking/_DockingMenu.py @@ -111,7 +111,8 @@ def site_pressed(self, button): self.refresh_run_btn_unusable() def refresh_run_btn_unusable(self, update=True): - if self._selected_receptor != None and len(self._selected_ligands) > 0 and self._selected_site != None: + site_requirement_met = self._selected_site != None or not self._plugin._calculations.requires_site + if self._selected_receptor != None and len(self._selected_ligands) > 0 and site_requirement_met: self._run_button.text.value_unusable = "Running..." self._run_button.unusable = False else: @@ -168,6 +169,11 @@ def reset(self, update_menu=True): self.make_plugin_usable() self._plugin.update_menu(self._menu) + def open_menu(self): + self._plugin.menu = self._menu + self._plugin.menu.enabled = True + self._plugin.update_menu(self._plugin.menu) + def build_menu(self): # defining callbacks def run_button_pressed_callback(button): diff --git a/publish.sh b/publish.sh old mode 100644 new mode 100755 diff --git a/setup.py b/setup.py index efe8a4d..79b4f8e 100644 --- a/setup.py +++ b/setup.py @@ -1,12 +1,13 @@ -import pathlib +import os from setuptools import find_packages, setup -README = (pathlib.Path(__file__).parent / "README.md").read_text() +with open(os.path.join(os.path.dirname(__file__), "README.md"), 'r') as file: + README = file.read() setup( name = 'nanome-docking', packages=find_packages(), - version = '0.1.3', + version = '0.1.5', license='MIT', description = 'Nanome Plugin to dock ligands to a receptor', long_description = README, From c36bc52eff944ff68ffe30c67e65a4dfc7c6225e Mon Sep 17 00:00:00 2001 From: Max Howard Date: Tue, 5 Nov 2019 17:01:47 -0800 Subject: [PATCH 19/19] hop --- nanome_docking/_DockingCalculations.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/nanome_docking/_DockingCalculations.py b/nanome_docking/_DockingCalculations.py index f03668a..fee1e59 100644 --- a/nanome_docking/_DockingCalculations.py +++ b/nanome_docking/_DockingCalculations.py @@ -95,9 +95,6 @@ def _check_conversion(self): def _start_docking(self): exe_path = os.path.join(os.path.dirname(__file__), 'smina') - - receptor_input_name = os.path.join(os.path.dirname(__file__), '1OYT-receptor.pdb') - ligand_input_name = os.path.join(os.path.dirname(__file__), '1OYT-FSN.pdb') if self._scoring: smina_args = [exe_path, '-r', self._receptor_input.name, '-l', self._ligands_input.name, '--autobox_ligand', self._site_input.name, '--score_only', '--out', self._ligand_output.name]