Пример #1
0
    def __init__(self,
                 path,
                 grid_extension=".grd",
                 zip_results=True,
                 settings=None):
        if settings is None:
            self.settings = self.Settings()
        else:
            self.settings = settings

        if grid_extension in self.settings.supported_grids:
            self.settings.grid_extension = grid_extension
        else:
            self.settings.grid_extension = ".grd"
            print(
                "WARNING: Invalid grid file format provided. Default: '.grd' will be used"
            )

        self.path = self.get_out_dir(path)

        self.zip_results = zip_results

        self.pymol_out = PyMOLFile()
        if self.zip_results:
            # unzip and change working directory
            self.pymol_out.commands += PyMOLCommands.unzip_dir(
                self.settings.container)
Пример #2
0
        def visualise(g, gname, peaks):
            # visualise
            gobj_name = f"{gname}_grid"
            surface_objname = f"surface_{gobj_name}"
            vis = f"testdata/grid_extension/{gname}.py"
            gpath = f"testdata/grid_extension/{gname}.grd"

            g.write(gpath)

            f = PyMOLFile()
            f.commands += PyMOLCommands.load(fname=f"{gname}.grd",
                                             objname=gobj_name)
            f.commands += PyMOLCommands.isosurface(
                grd_name=gobj_name,
                isosurface_name=surface_objname,
                level=5,
                color="yellow")

            for i, p in enumerate(peaks):
                f.commands += PyMOLCommands.sphere(objname=f"peak_obj_{i}",
                                                   rgba=[1, 1, 1, 1],
                                                   coords=p,
                                                   radius=0.5)
                f.commands += PyMOLCommands.load_cgo(obj=f"peak_obj_{i}",
                                                     objname=f"peak_{i}")

            f.write(vis)
Пример #3
0
    def test_neighbourhood(self):
        # check the catchment critera
        neighbours = Grid.neighbourhood(i=0,
                                        j=0,
                                        k=0,
                                        high=self.buriedness.nsteps,
                                        catchment=1)
        self.assertEqual(3, len(neighbours))

        neighbours1 = Grid.neighbourhood(i=5,
                                         j=5,
                                         k=5,
                                         high=self.buriedness.nsteps,
                                         catchment=1)
        self.assertEqual(6, len(neighbours1))

        f = PyMOLFile()
        for i, n in enumerate(neighbours + neighbours1):
            f.commands += PyMOLCommands.sphere(f"sphere_{i}", (0, 0, 1, 1), n,
                                               0.1)
            f.commands += PyMOLCommands.load_cgo(f"sphere_{i}",
                                                 f"sphere_{i}_obj")
        f.commands += PyMOLCommands.sphere("centre", (1, 0, 0, 1), (5, 5, 5),
                                           0.1)
        f.commands += PyMOLCommands.load_cgo("centre", "centre_obj")
        f.commands += PyMOLCommands.sphere("centre1", (1, 0, 0, 1), (0, 0, 0),
                                           0.1)
        f.commands += PyMOLCommands.load_cgo("centre1", "centre1_obj")

        f.write("testdata/grid_extension/neighbourhood.py")
Пример #4
0
    def testto_pymol_str(self):
        self.ligand_pharmacophore.feature_definitions = ["acceptor_projected"]
        self.ligand_pharmacophore.detect_from_ligand(ligand=self.crystal)

        f = PyMOLFile()
        f.commands += self.ligand_pharmacophore.detected_features[
            0].to_pymol_str()
        f.write(
            "testdata/pharmacophore_extension/LigandPharmacophoreModel/from_ligand/feature_write.py"
        )
Пример #5
0
    def test_edge_detection(self):
        self.selected = Grid.from_file("testdata/result/molA.grd")
        edge = self.selected.edge_detection()

        self.assertLess(len(edge), self.selected.count_grid())
        f = PyMOLFile()
        for i, n in enumerate(edge):
            f.commands += PyMOLCommands.sphere(f"sphere_{i}", (0, 0, 1, 1), n,
                                               0.1)
            f.commands += PyMOLCommands.load_cgo(f"sphere_{i}",
                                                 f"sphere_{i}_obj")

        f.write("testdata/grid_extension/edge_detection.py")
Пример #6
0
def create_pymol_file(residues, pdb):
    f = PyMOLFile()

    f.commands += PyMOLCommands.load(f"{pdb.upper()}.pdb", pdb)
    f.commands += PyMOLCommands.hide("sticks")

    for residue in residues:
        f.commands += PyMOLCommands.select("sele", f"resi {residue[3:]}")
        f.commands += PyMOLCommands.show("stick", "sele")

    f.commands += PyMOLCommands.load(f"{pdb}_ref.mol2", "lig")
    return f
Пример #7
0
 def setUp(self):
     self.pymol_file = PyMOLFile()
     self.pomegranate = (240 / 255, 52 / 255, 52 / 255, 0.5)
Пример #8
0
class TestPyMOLWrapper(unittest.TestCase):
    def setUp(self):
        self.pymol_file = PyMOLFile()
        self.pomegranate = (240 / 255, 52 / 255, 52 / 255, 0.5)

    def test_sphere(self):
        self.pymol_file.commands += PyMOLCommands.sphere("_mysphere",
                                                         self.pomegranate,
                                                         (0, 0, 0),
                                                         radius=2)
        self.pymol_file.commands += PyMOLCommands.load_cgo(
            "_mysphere", "mysphere")

        self.pymol_file.commands += PyMOLCommands.sphere("_mysphere1",
                                                         self.pomegranate,
                                                         (1, 1, 1),
                                                         radius=1)
        self.pymol_file.commands += PyMOLCommands.load_cgo(
            "_mysphere1", "mysphere1")

        self.pymol_file.write("testdata/wrapper_pymol/test_sphere.py")

    def test_cylinder(self):
        self.pymol_file.commands += PyMOLCommands.cylinder(
            "_mycylinder", (0, 0, 0), (1, 1, 1), 2, (1, 0, 0, 0.5))
        self.pymol_file.commands += PyMOLCommands.load_cgo(
            "_mycylinder", "mycylinder")

        self.pymol_file.commands += PyMOLCommands.cylinder(
            "_mycylinder2", (0, 0, 0), (10, 10, 10), 0.2, (1, 0, 0, 1),
            (0.5, 0.5, 0))
        self.pymol_file.commands += PyMOLCommands.load_cgo(
            "_mycylinder2", "mycylinder2")

        self.pymol_file.write("testdata/wrapper_pymol/test_cylinder.py")

    def test_cone(self):
        self.pymol_file.commands += PyMOLCommands.cone("_mycone", (0, 0, 0),
                                                       (10, 10, 10), 5,
                                                       (1, 0, 0))
        self.pymol_file.commands += PyMOLCommands.load_cgo("_mycone", "mycone")

        self.pymol_file.write("testdata/wrapper_pymol/test_cone.py")

    def test_arrow(self):
        self.pymol_file.commands += PyMOLCommands.arrow(
            "_myarrow", (1, 1, 0), (4, 5, 0), (1, 0, 0), (0, 0, 1))
        self.pymol_file.commands += PyMOLCommands.load_cgo(
            "_myarrow", "myarrow")

        self.pymol_file.write("testdata/wrapper_pymol/test_arrow.py")

    def test_pseudoatom(self):
        self.pymol_file.commands += PyMOLCommands.pseudoatom(
            "mypseudoatom", (1, 1, 1), self.pomegranate)

        self.pymol_file.commands += PyMOLCommands.pseudoatom(
            "mypseudoatom2", (2, 2, 2), self.pomegranate, "31.2")

        self.pymol_file.write("testdata/wrapper_pymol/test_pseudoatom.py")

    def test_line(self):
        self.pymol_file.commands += PyMOLCommands.line("myline", (1, 1, 1),
                                                       (2, 2, 2),
                                                       self.pomegranate,
                                                       width=4)

        self.pymol_file.commands += PyMOLCommands.line("myline2", (1, 1, 1),
                                                       (0, 0, 0),
                                                       self.pomegranate,
                                                       width=10)

        self.pymol_file.write("testdata/wrapper_pymol/test_line.py")

    def test_grid(self):
        self.pymol_file.commands += PyMOLCommands.load("test_grid.grd",
                                                       "mygrid")
        self.pymol_file.write("testdata/wrapper_pymol/test_grid.py")

    def test_isosurface(self):
        self.pymol_file.commands += PyMOLCommands.set_color(
            "pomegranate", self.pomegranate)
        self.pymol_file.commands += PyMOLCommands.isosurface(
            "test_grid.grd", "mygrid", "mysurface", 4, "pomegranate")

        self.pymol_file.write("testdata/wrapper_pymol/test_isosurface.py")

    def test_load(self):
        self.pymol_file.commands += PyMOLCommands.load("test_protein.pdb",
                                                       "myprotein")
        self.pymol_file.write("testdata/wrapper_pymol/test_load.py")

    def test_group(self):
        self.pymol_file.commands += PyMOLCommands.line("myline1", (0, 0, 0),
                                                       (1, 1, 1),
                                                       self.pomegranate,
                                                       width=10)

        self.pymol_file.commands += PyMOLCommands.pseudoatom(
            "mypseudoatom1", (0, 0, 0), self.pomegranate)

        self.pymol_file.commands += PyMOLCommands.pseudoatom(
            "mypseudoatom2", (1, 1, 1), self.pomegranate)
        self.pymol_file.commands += PyMOLCommands.group(
            "mygroup", ["myline1", "mypseudoatom1", "mypseudoatom2"])

        self.pymol_file.write("testdata/wrapper_pymol/test_group.py")
Пример #9
0
    def pymol_visulisation(self, outdir=None, fname="pymol_file.py"):
        if not outdir:
            outdir = os.getcwd()

        if not os.path.exists(outdir):
            os.mkdir(outdir)

        if self.ligands:
            with MoleculeWriter(os.path.join(outdir, "ligands.mol2")) as w:
                for ligand in self.ligands:
                    try:
                        w.write(ligand.molecule)
                    except AttributeError:
                        w.write(ligand)

        if self.protein:
            with MoleculeWriter(os.path.join(outdir, "protein.mol2")) as w:
                w.write(self.protein.molecule)

        self.pymol_out = PyMOLFile()

        if self.ligands:
            self.pymol_out.commands += PyMOLCommands.load(
                "ligands.mol2", "ligands")

        if self.protein:
            self.pymol_out.commands += PyMOLCommands.load(
                "protein.mol2", "protein")

        # write out point spheres and projection sphere and lines if applicable
        self.pymol_out.commands += self.features_to_pymol_strings(
            self.detected_features)

        if self.feature_point_grids:
            for identifier, g in self.feature_point_grids.items():
                g.write(os.path.join(outdir, f"{identifier}.grd"))

                point_colour = rgb_to_decimal(
                    self.feature_definitions[identifier].colour)
                self.pymol_out.commands += PyMOLCommands.set_color(
                    f"{identifier}_color", point_colour)
                self.pymol_out.commands += PyMOLCommands.load(
                    f"{identifier}.grd", f"{identifier}_grid")
                self.pymol_out.commands += PyMOLCommands.isosurface(
                    f"{identifier}_grid",
                    f"surface_{identifier}",
                    level=1,
                    color=f"{identifier}_color")

            self.pymol_out.commands += PyMOLCommands.group(
                "feature_grids", self.feature_point_grids.keys())
            self.pymol_out.commands += PyMOLCommands.group(
                "feature_grids",
                [f"surface_{a}" for a in self.feature_point_grids])

            min_value = 0
            surface_dic = {
                self.identifier: {
                    'feature_grids':
                    [f"surface_{g}" for g in self.feature_point_grids.keys()]
                }
            }

            surface_value_dic = {
                self.identifier: {
                    "feature_grids":
                    max([
                        round(g.extrema[1], 1)
                        for g in self.feature_point_grids.values()
                    ])
                }
            }

            self.pymol_out.commands += PyMOLCommands.isoslider(
                surface_dic, surface_value_dic)

        self.pymol_out.write(os.path.join(outdir, fname))
Пример #10
0
class PharmacophoreModel(Pharmacophore.Query):
    """
    Base Class for the representing a CrossMiner pharmacophore query. Used to
    generate more specific PharmacophoreModels
    """
    class Settings:
        def __init__(self):
            self.x = 1

    def __init__(self, features=None, _motif_pharmacophore=None):
        super().__init__(features=features,
                         _motif_pharmacophore=_motif_pharmacophore)
        self.cm_dir = os.path.dirname(os.path.dirname(csd_directory()))

        feat_db = os.environ.get(
            "CCDC_CROSSMINER_FEATURE_DEFINITIONS",
            os.path.join(self.cm_dir, "../CSD_CrossMiner/feature_definitions"))

        Pharmacophore.read_feature_definitions(directory=feat_db)
        self.__feature_options = {
            k: v
            for k, v in Pharmacophore.feature_definitions.items()
        }
        assert len(self.__feature_options) > 1

        self.__feature_definitions = self.__feature_options

        self.tmp = tempfile.mkdtemp()
        self.__identifier = None
        self.__ligands = None
        self.__protein = None
        self.__detected_features = None
        self.__feature_point_grids = None

    def __len__(self):
        return len(self.__features)

    @property
    def identifier(self):
        return self.__identifier

    @identifier.setter
    def identifier(self, ident):
        self.__identifier = ident

    @property
    def ligands(self):
        return self.__ligands

    @ligands.setter
    def ligands(self, ligands):
        self.__ligands = ligands

    @property
    def protein(self):
        return self.__protein

    @protein.setter
    def protein(self, protein):
        self.__protein = protein

    @property
    def feature_point_grids(self):
        return self.__feature_point_grids

    @feature_point_grids.setter
    def feature_point_grids(self, dict):
        self.__feature_point_grids = dict

    @property
    def detected_features(self):
        return self.__detected_features

    @detected_features.setter
    def detected_features(self, features):
        self.__detected_features = features

    @property
    def feature_definitions(self):
        return self.__feature_definitions

    @feature_definitions.setter
    def feature_definitions(self, feature_types):
        # reset before choosing
        self.__feature_definitions = {
            k: v
            for k, v in self.__feature_options.items()
            if any([k == ft for ft in feature_types])
        }

    @staticmethod
    def from_file(file_name):
        '''Read a pharmacophore query from a file.'''
        reader = MotifPharmacophoreLib.MotifPharmacophoreReader(file_name)
        q = __class__(_motif_pharmacophore=reader.pharmacophore())
        q._features_from_pharmacophore()
        for f in q.features:
            f._query = q
        return q

    def to_gold_conf(self, scaling="BLOCK", fitting_points=0, score=10):
        crossminer_to_gold = {
            "acceptor_projected": "ACC",
            "acceptor": "ACC",
            "donor_projected": "DON",
            "ring": "RING_CNT",
            "ring_projected": "RING_CNT"
        }

        body = ""
        for feat in self.features:
            ident = crossminer_to_gold[feat.identifier]
            x = feat.spheres[0].centre[0]
            y = feat.spheres[0].centre[1]
            z = feat.spheres[0].centre[2]
            body += f"constraint pharmacophore {ident} {scaling} {x} {y} {z} {fitting_points} {feat.spheres[0].radius} {score}"
            if fitting_points == 1:
                body += " 1.0\n"
            else:
                body += "\n"
        return body

    def top_features(self, num, point=True, projection=True):
        feature_by_score = {}
        for feature in self.detected_features:
            score = []
            if point:
                score.append(feature.score)
            elif projection:
                score.append(feature.projected_value)

            feature_by_score.update({feature: sum(score)})

        print(feature_by_score)

        return list(
            OrderedDict(
                sorted(feature_by_score.items(),
                       key=lambda item: item[1],
                       reverse=True)).keys())[:num]

    def to_csv(self, fname):
        vars = {}
        feat_def, point_scores, projected_scores, xs, ys, zs = zip(*[[
            feat.identifier, feat.score, feat.projected_value, feat.spheres[0].
            centre[0], feat.spheres[0].centre[1], feat.spheres[0].centre[2]
        ] for feat in self.detected_features])
        vars.update({
            "feat_def": feat_def,
            "point_scores": point_scores,
            "projected_scores": projected_scores,
            "x": xs,
            "y": ys,
            "z": zs
        })

        if self.ligands:
            total_ligs = len(self.ligands)
            point_perc, projected_perc = zip(
                *[[(feat.score / total_ligs) *
                   100, (feat.projected_value / total_ligs) * 100]
                  for feat in self.detected_features])
            vars.update({
                "point_perc": point_perc,
                "projected_perc": projected_perc
            })

        df = pd.DataFrame(vars)

        df.to_csv(fname)

    def features_to_pymol_strings(self, features):
        """
        creates the code to visualise `ccdc.pharmacophore.Pharmacophore.Features` in PyMOL

        :param list of (`ccdc.pharmacophore.Pharmacophore.Features`) features: features to be visualised
        :return: str python code
        """
        group_dic = {ident: [] for ident in self.feature_definitions.keys()}
        pymol_out = ''

        for i, feat in enumerate(features):
            pymol_out += feat.to_pymol_str(i=i)
            group_dic[feat.identifier].append(f"{feat.identifier}_{i}")

            if feat.projected_identifier and self.protein:
                resnum = feat.projected_identifier.split("/")[1]
                # TODO: clean up
                pymol_out += f'\ncmd.select("sele", "resi {resnum}")\ncmd.show("sticks", "sele")'

        for fd in self.feature_definitions.keys():
            pymol_out += PyMOLCommands.group(f"{fd}_pts", group_dic[fd])
        pymol_out += PyMOLCommands.group(
            "ligand_pharmacophore", [f"{a}_pts" for a in group_dic.keys()])

        return pymol_out

    def pymol_visulisation(self, outdir=None, fname="pymol_file.py"):
        if not outdir:
            outdir = os.getcwd()

        if not os.path.exists(outdir):
            os.mkdir(outdir)

        if self.ligands:
            with MoleculeWriter(os.path.join(outdir, "ligands.mol2")) as w:
                for ligand in self.ligands:
                    try:
                        w.write(ligand.molecule)
                    except AttributeError:
                        w.write(ligand)

        if self.protein:
            with MoleculeWriter(os.path.join(outdir, "protein.mol2")) as w:
                w.write(self.protein.molecule)

        self.pymol_out = PyMOLFile()

        if self.ligands:
            self.pymol_out.commands += PyMOLCommands.load(
                "ligands.mol2", "ligands")

        if self.protein:
            self.pymol_out.commands += PyMOLCommands.load(
                "protein.mol2", "protein")

        # write out point spheres and projection sphere and lines if applicable
        self.pymol_out.commands += self.features_to_pymol_strings(
            self.detected_features)

        if self.feature_point_grids:
            for identifier, g in self.feature_point_grids.items():
                g.write(os.path.join(outdir, f"{identifier}.grd"))

                point_colour = rgb_to_decimal(
                    self.feature_definitions[identifier].colour)
                self.pymol_out.commands += PyMOLCommands.set_color(
                    f"{identifier}_color", point_colour)
                self.pymol_out.commands += PyMOLCommands.load(
                    f"{identifier}.grd", f"{identifier}_grid")
                self.pymol_out.commands += PyMOLCommands.isosurface(
                    f"{identifier}_grid",
                    f"surface_{identifier}",
                    level=1,
                    color=f"{identifier}_color")

            self.pymol_out.commands += PyMOLCommands.group(
                "feature_grids", self.feature_point_grids.keys())
            self.pymol_out.commands += PyMOLCommands.group(
                "feature_grids",
                [f"surface_{a}" for a in self.feature_point_grids])

            min_value = 0
            surface_dic = {
                self.identifier: {
                    'feature_grids':
                    [f"surface_{g}" for g in self.feature_point_grids.keys()]
                }
            }

            surface_value_dic = {
                self.identifier: {
                    "feature_grids":
                    max([
                        round(g.extrema[1], 1)
                        for g in self.feature_point_grids.values()
                    ])
                }
            }

            self.pymol_out.commands += PyMOLCommands.isoslider(
                surface_dic, surface_value_dic)

        self.pymol_out.write(os.path.join(outdir, fname))

    # STATIC METHODS
    @staticmethod
    def _get_crystal(obj):
        """
        Convert a obj's writable by MoleculeWriter to a crystal

        :param `ccdc.molecule.Molecule` obj: molecule or protein
        :return: `ccdc.crystal.Crystal`
        """
        tmp = tempfile.mkdtemp()
        f = os.path.join(tmp, "obj.mol2")
        with MoleculeWriter(f) as w:
            w.write(obj)
        return CrystalReader(f)[0]
Пример #11
0
class HotspotWriter(Helper):
    """
    A class to handle the writing of a :class`hotspots.result.Result`. Additionally, creation of the
    PyMol visualisation scripts are handled here.

    :param str path: path to output directory
    :param str visualisation: "pymol" or "ngl" currently only PyMOL available
    :param str grid_extension: ".grd", ".ccp4" and ".acnt" supported
    :param bool zip_results: If True, the result directory will be compressed. (recommended)
    :param `hotspots.hs_io.HotspotWriter.Settings` settings: settings
    """
    class Settings(object):
        """
        A class to hold the :class:`hotspots.hs_io.HotspotWriter` settings
        """
        def __init__(self):
            self.output_superstar = False
            self.output_weighted = False
            self.output_buriedness = True
            self.grid_extension = ".grd"
            self.bg_color = "white"
            self.surface = False
            self.surface_trim_factor = 13
            self.organic_sticks = True
            self.isosurface_threshold = [10, 14, 17]
            self.grids = None
            self.transparency = 0.2
            self.grid_labels = True
            self.supported_grids = [".grd", ".ccp4", ".acnt"]
            self.pharmacophore = False
            self.pharmacophore_labels = True
            self.pharmacophore_format = [".py"]
            self.container = 'out'
            self.identifier_tag = [0]
            # e.g. self.protein_color_dic = {f"protein_{hr.identifier}": "slate"}
            self.protein_color_dic = {}
            self.colour_dict = {
                'acceptor': 'red',
                'donor': 'blue',
                'apolar': 'yellow',
                'negative': 'purple',
                'positive': 'cyan',
                'buriedness': 'gray'
            }

    def __init__(self,
                 path,
                 grid_extension=".grd",
                 zip_results=True,
                 settings=None):
        if settings is None:
            self.settings = self.Settings()
        else:
            self.settings = settings

        if grid_extension in self.settings.supported_grids:
            self.settings.grid_extension = grid_extension
        else:
            self.settings.grid_extension = ".grd"
            print(
                "WARNING: Invalid grid file format provided. Default: '.grd' will be used"
            )

        self.path = self.get_out_dir(path)

        self.zip_results = zip_results

        self.pymol_out = PyMOLFile()
        if self.zip_results:
            # unzip and change working directory
            self.pymol_out.commands += PyMOLCommands.unzip_dir(
                self.settings.container)

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        if traceback:
            print(traceback)

    def write(self, hr):
        """
        writes the Fragment Hotspot Maps result to the output directory and create the pymol visualisation file

        :param hr: a Fragment Hotspot Maps result or list of results
        :type hr: `hotspots.result.Result`

        >>> from hotspots.calculation import Runner
        >>> from hotspots.hs_io import HotspotWriter

        >>> r = Runner
        >>> result = r.from_pdb("1hcl")
        >>> out_dir = <path_to_out>
        >>> with HotspotWriter(out_dir) as w:
        >>>     w.write(result)

        """
        container = Helper.get_out_dir(join(self.path,
                                            self.settings.container))

        if isinstance(hr, list):
            print(hr)
            if len({h.identifier for h in hr}) != len(hr):
                # if there are not unique identifiers, create some.
                for i, h in enumerate(hr):
                    h.identifier = f"hotspot-{i}"
            for h in hr:
                self._single_write(container, h)

        else:
            if not hr.identifier:
                hr.identifier = "hotspot"
            self._single_write(container, hr)

        self._write_pymol_isoslider(hr)
        self.pymol_out.commands += PyMOLCommands.background_color(
            self.settings.bg_color)
        self.pymol_out.commands += PyMOLCommands.push_to_wd()

        if self.zip_results:
            self.compress()

        self.pymol_out.write(join(self.path, "pymol_file.py"))

    def _single_write(self, path, hr):
        hr.out_dir = Helper.get_out_dir(join(path, hr.identifier))

        self._write_grids(hr)
        self._write_protein(hr.out_dir, hr.protein)

        relpath = f'{hr.identifier}'
        self._write_pymol_objects(relpath, hr)

    def _write_grids(self, hr):
        """
        Write probe grids to output directory

        :param grid_dict: hotspot result grid dict
        :param buriedness: buriedness grid

        :type grid_dict: hotspot.grid_extension.Grid
        :type buriedness: hotspot.grid_extension.Grid
        """
        for p, g in hr.super_grids.items():
            g.write(join(hr.out_dir, f"{p}{self.settings.grid_extension}"))

        if self.settings.output_buriedness and hr.buriedness:
            hr.buriedness.write(
                join(hr.out_dir, f"buriedness{self.settings.grid_extension}"))

        if self.settings.output_superstar and hr.superstar:
            for p, g in hr.superstar.items():
                g.write(
                    join(hr.out_dir,
                         f"superstar_{p}{self.settings.grid_extension}"))

        if self.settings.output_weighted and hr.weighted_superstar:
            for p, g in hr.weighted_superstar.items():
                g.write(
                    join(hr.out_dir,
                         f"weighted_{p}{self.settings.grid_extension}"))

    @staticmethod
    def _write_protein(path, prot):
        """
        writes protein to output directory

        :param prot: a protein
        :type prot: `ccdc.protein.Protein`

        """
        with io.MoleculeWriter(join(path, "protein.pdb")) as writer:
            writer.write(prot)

    def _write_pymol_isoslider(self, hr):
        """
        generates the commands for an isoslider

        :param hr: a hotspot result
        :type hr: `hotspots.results.Results`
        """
        # Isosurface obj's take the name: "surface_{probe ID}_{hotpsot ID}"
        # e.g. "surface_apolar_hotspotA"
        if not isinstance(hr, list):
            hr = [hr]

        # the hotspot grids are always output
        surface_dic = {
            h.identifier: {
                'fhm':
                [f"surface_{g}_{h.identifier}" for g in h.super_grids.keys()]
            }
            for h in hr
        }

        surface_value_dic = {
            h.identifier: {
                "fhm":
                max([round(g.extrema[1], 1) for g in h.super_grids.values()])
            }
            for h in hr
        }

        for h in hr:
            if self.settings.output_superstar and h.superstar:
                surface_dic[h.identifier].update({
                    'superstar': [
                        f"surface_superstar_{g}_{h.identifier}"
                        for g in h.superstar.keys()
                    ]
                })

                surface_value_dic[h.identifier].update({
                    'superstar':
                    max([round(g.extrema[1], 1) for g in h.superstar.values()])
                })

            if self.settings.output_weighted and h.weighted_superstar:
                surface_dic[h.identifier].update({
                    'weighted': [
                        f"surface_weighted_superstar_{g}_{h.identifier}"
                        for g in h.weighted_superstar.keys()
                    ]
                })

                surface_value_dic[h.identifier].update({
                    'weighted':
                    max([
                        round(g.extrema[1], 1)
                        for g in h.weighted_superstar.values()
                    ])
                })

            if self.settings.output_buriedness and h.buriedness:
                surface_dic[h.identifier].update(
                    {'buriedness': [f"surface_buriedness_{h.identifier}"]})

                surface_value_dic[h.identifier].update({'buriedness': 8})

        min_value = 0
        print(surface_dic)
        print(surface_value_dic)

        self.pymol_out.commands += PyMOLCommands.isoslider(
            surface_dic, surface_value_dic)

    def _write_pymol_isosurfaces(self, dict, relpath, identifier, dict_type):
        """
        Loads grids and generates isosurfaces

        :param dict: interaction grid dictionary
        :param relpath: result containing directory
        :param identifier: hotspot identifier
        :param dict_type: superstar, fhm or weighted_superstar

        :type dict: dict
        :type relpath: str
        :type identifier: str
        :type dict_type: str

        :return: pymol commands
        :rtype: str
        """
        cmd = ""
        default_level = 5
        # load grids and create isosurfaces
        group_members = []
        for p in dict.keys():
            if dict_type == 'fhm':
                objname = f'{p}_{identifier}'
                fname = f'{relpath}/{p}{self.settings.grid_extension}'
            else:
                objname = f'{dict_type}_{p}_{identifier}'
                fname = f'{relpath}/{dict_type}_{p}{self.settings.grid_extension}'
            cmd += PyMOLCommands.load(fname=fname, objname=objname)

            # surface_10_apolar_hotspotid
            surface_objname = f'surface_{objname}'
            cmd += PyMOLCommands.isosurface(grd_name=objname,
                                            isosurface_name=surface_objname,
                                            level=default_level,
                                            color=self.settings.colour_dict[p])

            cmd += PyMOLCommands.pymol_set(setting_name='transparency',
                                           value=self.settings.transparency,
                                           selection=surface_objname)

            group_members.extend([objname, f"surface_{objname}"])

        cmd += PyMOLCommands.group(group_name=identifier,
                                   members=group_members)
        return cmd

    def _write_pymol_objects(self, relpath, hr, load_prot=True):
        """
        generates pymol commands associated with an indivdual hotspot

        :param relpath: path to the directory holding associated files
        :param hr: hotspot result

        :type relpath: str
        :type hr: `hotspots.results.Results`

        """
        self.pymol_out.commands += self._write_pymol_isosurfaces(
            hr.super_grids, relpath, hr.identifier, "fhm")

        if self.settings.output_superstar and hr.superstar:
            self.pymol_out.commands += self._write_pymol_isosurfaces(
                hr.superstar, relpath, hr.identifier, "superstar")

        if self.settings.output_weighted and hr.weighted_superstar:
            self.pymol_out.commands += self._write_pymol_isosurfaces(
                hr.weighted_superstar, relpath, hr.identifier, "weighted")

        if self.settings.output_buriedness and hr.buriedness:
            default_level = 3
            objname = f'buriedness_{hr.identifier}'
            fname = f'{relpath}/buriedness{self.settings.grid_extension}'

            self.pymol_out.commands += PyMOLCommands.load(fname=fname,
                                                          objname=objname)

            # surface_10_apolar_hotspotid
            surface_objname = f'surface_{objname}'
            self.pymol_out.commands += PyMOLCommands.isosurface(
                grd_name=objname,
                isosurface_name=surface_objname,
                level=default_level,
                color=self.settings.colour_dict["buriedness"])

            self.pymol_out.commands += PyMOLCommands.pymol_set(
                setting_name='transparency',
                value=self.settings.transparency,
                selection=surface_objname)

        group_members = [
            f'buriedness_{hr.identifier}',
            f'surface_buriedness_{hr.identifier}'
        ]

        self.pymol_out.commands += PyMOLCommands.group(
            group_name=hr.identifier, members=group_members)

        # generate grid labels
        labels = hr.grid_labels()

        for p, dic in labels.items():
            i = 0
            group_me = []
            for coord, value in dic.items():
                objname = f"PS_{p}_{hr.identifier}_{i}"
                group_me.append(objname)
                self.pymol_out.commands += PyMOLCommands.pseudoatom(
                    objname=objname, coords=coord, label=f'{round(value, 1)}')
                group_me.append(objname)
                i += 1
            self.pymol_out.commands += PyMOLCommands.group(
                f'label_{p}_{hr.identifier}', group_me)

        self.pymol_out.commands += PyMOLCommands.group(
            f"labels_{hr.identifier}",
            [f'label_{p}_{hr.identifier}' for p in hr.super_grids.keys()])

        # load up the protein
        if load_prot:
            self.pymol_out.commands += PyMOLCommands.load(
                f'{relpath}/protein.pdb', f'protein_{hr.identifier}')
            if len(self.settings.protein_color_dic) > 0:
                self.pymol_out += PyMOLCommands.color(
                    "slate", f'protein_{hr.identifier}')
            self.pymol_out.commands += PyMOLCommands.show(
                "cartoon", f'protein_{hr.identifier}')
            self.pymol_out.commands += PyMOLCommands.hide(
                "line", f'protein_{hr.identifier}')
            self.pymol_out.commands += PyMOLCommands.show("sticks", "organic")

        # find contributing residues

    def compress(self, delete_directory: bool = True) -> None:
        """
        compresses the output directory created for this :class:`hotspots.HotspotResults` instance, and
        removes the directory by default. The zipped file can be loaded directly into a new
        :class:`hotspots.HotspotResults` instance using the
        :func:`~hotspots.Hotspots.from_zip_dir` function

        :param bool delete_directory: remove the out directory once it has been zipped
        """
        out_dir = join(self.path, self.settings.container)
        shutil.make_archive(out_dir, 'zip', out_dir)
        if delete_directory:
            shutil.rmtree(join(self.path, self.settings.container))