Ejemplo n.º 1
0
    def view3d(i=0):
        '''Simple structure viewer that uses py3Dmol to view PDB structure by
        indexing the list of PDBids

        Parameters
        ----------
            i (int): index of the protein if a list of PDBids
        '''
        print(f"PdbID: {pdbIds[i]}, Style: {style}")

        if '.' not in pdbIds[i]:
            viewer = py3Dmol.view(query='pdb:' + pdbIds[i],
                                  options={'doAssembly': bioAssembly})
            viewer.setStyle({style: {'color': color}})
            viewer.setStyle({'hetflag': True},
                            {'stick': {
                                'singleBond': False
                            }})

        else:
            pdbid, chainid = pdbIds[i].split('.')
            viewer = py3Dmol.view(query='pdb:' + pdbid,
                                  options={'doAssembly': bioAssembly})
            viewer.setStyle({})
            viewer.setStyle({'chain': chainid}, {style: {'color': color}})
            viewer.setStyle({
                'chain': chainid,
                'hetflag': True
            }, {'stick': {
                'singleBond': False
            }})
            viewer.zoomTo({'chain': chainid})

        return viewer.show()
Ejemplo n.º 2
0
def show_sticks(xyz=None, species=None, project_directory=None):
    """
    Draws the molecule in a "sticks" style according to the supplied xyz coordinates
    Returns whether successful of not
    If successful, save an image using draw_3d
    """
    xyz = check_xyz_species_for_drawing(xyz, species)
    coordinates, _, _, _, _ = get_xyz_matrix(xyz)
    s_mol, b_mol = molecules_from_xyz(xyz)
    mol = b_mol if b_mol is not None else s_mol
    try:
        _, rd_mol, _ = rdkit_conf_from_mol(mol, coordinates)
    except ValueError:
        return False
    mb = Chem.MolToMolBlock(rd_mol)
    p = p3d.view(width=400, height=400)
    p.addModel(mb, 'sdf')
    p.setStyle({'stick': {}})
    # p.setBackgroundColor('0xeeeeee')
    p.zoomTo()
    p.show()
    draw_3d(xyz=xyz,
            species=species,
            project_directory=project_directory,
            save_only=True)
    return True
Ejemplo n.º 3
0
    def view3d(i=0):
        '''Simple structure viewer that uses py3Dmol to view PDB structure by
        indexing the list of PDBids
        Attributes
        ----------
        i (int): index of the protein if a list of PDBids
        '''

        structures = df['pdbId'].iloc
        groups = df['groupNum0'].iloc
        chains = df['chain0'].iloc
        elements = df['element0'].iloc
        ori = str(df[sortBy].iloc[i])[:5]

        print(f"PDBId: {structures[i]}    chain: {chains[i]}    element:    {elements[i]}")
        print(f"{sortBy}: {ori}")

        viewer = py3Dmol.view(query='pdb:' + structures[i], width=700, height=700)
        neighbors = {'resi': get_neighbors_group(i), 'chain': get_neighbors_chain(i)}
        metal = {'resi': groups[i], 'atom': str(elements[i]).upper(), 'chain': chains[i]}

        viewer.setStyle(neighbors, {'stick': {'colorscheme': 'orangeCarbon'}})
        viewer.setStyle(metal, {'sphere': {'radius': 0.5, 'color': 'gray'}})

        viewer.zoomTo(neighbors)
        return viewer.show()
Ejemplo n.º 4
0
    def to_3Dmol(self, style=None, **kwargs):
        """Generate protein structure & return interactive py3Dmol.view for visualization.

        Args:
            style (str, optional): Style string to be passed to py3Dmol for
                visualization. Defaults to None.

        Returns:
            py3Dmol.view object: A view object that is interactive in iPython notebook
                settings.
        """
        import py3Dmol
        if not style:
            style = {
                'cartoon': {
                    'color': 'spectrum'
                },
                'stick': {
                    'radius': .15
                }
            }
        self._initialize_coordinates_and_PdbCreator()

        view = py3Dmol.view(**kwargs)
        view.addModel(self.pdb_creator.get_pdb_string(), 'pdb')
        if style:
            view.setStyle(style)
        view.zoomTo()
        return view
Ejemplo n.º 5
0
def show_structure(domain, full=False):
    '''
    Uses py3Dmol and requests to fetch domain PDB and show it in jupyter
    '''
    view = py3Dmol.view()

    def adjust_looks(view):
        view.setStyle({'cartoon': {'colorscheme': 'ssJmol'}})
        view.center()
        return view

    if full:
        prot = domain[:4].upper()
        if (prot + '.pdb') in os.listdir('structures'):
            with open('./structures/' + prot + '.pdb') as file:
                view.addModel(file.read(), 'pdb')
        else:
            r = requests.get('https://files.rcsb.org/download/' + prot +
                             '.pdb')
            with open('./structures/' + prot + '.pdb', 'w') as file:
                file.write(r.text)
            view = view.addModel(r.text, 'pdb')
    else:
        if (domain + '.pdb') in os.listdir('structures'):
            with open('./structures/' + domain + '.pdb') as file:
                view.addModel(file.read(), 'pdb')
        else:
            r = requests.get(
                'http://www.cathdb.info/version/v4_2_0/api/rest/id/' + domain +
                '.pdb')
            with open('./structures/' + domain + '.pdb', 'w') as file:
                file.write(r.text)
            view = view.addModel(r.text, 'pdb')
    return adjust_looks(view)
Ejemplo n.º 6
0
def display_molecules(molecules, size=(400, 300), animation=False):
    """
    display the molecules in Pymatgen object.

    Args:
        molecules: a list of pymatgen molecules
        size: (width, height) in tuple
        animation: whether or not display animation

    Returns:
        py3Dmol object

    """
    (width, height) = size
    view = py3Dmol.view(height=height, width=width)
    mol_strs = ""
    for mol in molecules:
        mol_strs += mol.to(fmt='xyz') + '\n'
    if animation:
        view.addModelsasFrames(mol_strs, 'xyz')
        view.animate({'loop': 'forward'})
    else:
        view.addModels(mol_strs, 'xyz')
    view.setStyle({'stick': {'colorscheme': 'greenCarbon'}})

    return view.zoomTo()
Ejemplo n.º 7
0
    def view3d(i=0):
        '''
        Simple structure viewer that zooms into a specified group and highlight
        its neighbors

        Attributes:
            i (int): index of the protein if a list of PDBids
        '''

        print(
            f"PDB: {pdbIds[i]}, group: {groups[i]}, chain: {chains[i]}, cutoffDistance: {distance}"
        )

        center = {'resi': groups[i], 'chain': chains[i]}
        neighbors = {
            'resi': groups[i],
            'chain': chains[i],
            'byres': 'true',
            'expand': distance
        }

        viewer = py3Dmol.view(query='pdb:' + pdbIds[i])
        viewer.zoomTo(center)
        viewer.setStyle(neighbors, {'stick': {}})
        viewer.setStyle(center, {'sphere': {'color': 'red'}})
        viewer.zoom(0.2, 1000)

        return viewer.show()
Ejemplo n.º 8
0
def drawConformer_episodic(data: dict,
                           confIds: List[int],
                           size: Tuple[int, int] = (300, 300),
                           style: str = "stick") -> py3Dmol.view:
    """Displays a specified conformer for each episode loaded in `data`.

    Parameters
    ----------
    data : dict from string to list
        Contains the loaded episode information. 'mol' must be a key in data and the corresponding list must contain
        RDKit Mol objects.
    confIds : list of int
        The indices for the conformers to be displayed (for each episode loaded in data).
    size : Tuple[int, int]
        The size of the display for each individual molecule (width, height).
    style: str
        The drawing style for displaying the molecule. Can be sphere, stick, line, cross, cartoon, and surface.
    """
    n = len(data['mol'])
    view = py3Dmol.view(width=size[0] * n,
                        height=size[0] * n,
                        linked=False,
                        viewergrid=(n, 1))
    for i in range(n):
        block = Chem.MolToMolBlock(data['mol'][i], confId=confIds[i])
        view.addModel(block, 'mol', viewer=(i, 0))
        view.setStyle({style: {}}, viewer=(i, 0))
    view.zoomTo()
    return view
 def __init__(self, xsize, ysize, nrow=1, ncol=1):
     from py3Dmol import view
     # set linked to False so that each structure can be rotated
     # independently
     self.xyzview = view(width=ncol * xsize,
                         height=nrow * ysize,
                         viewergrid=(nrow, ncol),
                         linked=False)
Ejemplo n.º 10
0
def display_pdb(path_to_pdb):
    with open(path_to_pdb) as ifile:
        protein = "".join([x for x in ifile])
    view = py3Dmol.view(width=400, height=300)
    view.addModelsAsFrames(protein)
    view.setStyle({'model': -1}, {"cartoon": {'color': 'spectrum'}})
    view.zoomTo()
    view.show()
Ejemplo n.º 11
0
def draw3d(mol_sd):
    fig = py3Dmol.view(width=600, height=400)
    if isinstance(mol_sd, str):
        fig.addModel(mol_sd, 'sdf')
    elif isinstance(mol_sd, list):
        for m in mol_sd:
            fig.addModel(m, 'sdf')
    fig.setStyle({'stick': {'colorscheme': 'grayCarbon'}})
    return fig.render()
Ejemplo n.º 12
0
def drawit(m,dimensions=(900,400),p=None,confId=-1):
    mb = Chem.MolToMolBlock(m,confId=confId)
    if p is None:
        p = py3Dmol.view(width=dimensions[0],height=dimensions[1])
    p.removeAllModels()
    p.addModel(mb,'sdf')
    p.setStyle({'stick':{}})
    p.setBackgroundColor('0xeeeeee')
    p.zoomTo()
    return p.show()
Ejemplo n.º 13
0
def display_atomic(struc,
                   size=(600, 300),
                   scale=0.25,
                   radius=0.10,
                   supercell=(1, 1, 1),
                   show_wp=False):
    """
    display the molecular crystals generated from pyxtal. If the animation is False, 
    only dump the structure to cif and let py3Dmol display it. If animation is on,
    show the generation of molecules in the crystal as an animation.

    Args:
        size: (width, height) in tuple
        scale: the size of sphere
        radius: the size of stick
        supercell: replicate the crystal (valid only when animation is False)
        show_wp: whether or not highlight the unique wyckoff site

    Returns:
        py3Dmol object
    """

    (width, height) = size
    view = py3Dmol.view(height=height, width=width)
    if struc.dim == 0:
        fmt = "xyz"
    else:
        fmt = "cif"

    txt = struc.to_file(fmt=fmt)
    view.addModel(txt, fmt, {
        'doAssembly': True,
        'duplicateAssemblyAtoms': True
    })
    view.setStyle({
        'sphere': {
            'colorscheme': 'Jmol',
            'scale': scale
        },
        'stick': {
            'colorscheme': 'Jmol',
            'radius': radius
        }
    })
    if struc.dim != 0:
        view.addUnitCell()
        A, B, C = supercell
        view.replicateUnitCell(A, B, C)
        if show_wp:
            view.setStyle({'sym': 2},
                          {'sphere': {
                              'scale': scale * 1.1,
                              'color': 'blue'
                          }})
    return view.zoomTo()
Ejemplo n.º 14
0
    def _view_3Dmol(self, **options):
        """
        Visualize the system using 3Dmol.js and py3Dmol.
        """
        from nappy.elements import elements
        try:
            import py3Dmol
        except Exception as e:
            raise

        if 'model' in options.keys():
            modopts = options['model']
        if 'volume' in options.keys():
            volopts = options['volume']

        pdb = nappy.io.get_PDB_txt(self, **options)
        v = py3Dmol.view()
        v.removeAllModels()
        v.setViewStyle({'style': 'outline', 'color': 'black', 'width': 0.03})
        v.addModel(pdb, 'pdb')
        colors = {s: elements[s]['CPKcolor'] for s in self.specorder}
        if 'modopts' in locals():
            v.setStyle(modopts)
        else:
            v.setStyle({
                'stick': {
                    'radius': .1,
                    'colorscheme': {
                        'prop': 'elem',
                        'map': colors
                    }
                },
                'sphere': {
                    'radius': .5,
                    'colorscheme': {
                        'prop': 'elem',
                        'map': colors
                    }
                }
            })
        v.addUnitCell()
        if hasattr(self, 'voldata'):
            cube = self.get_cube_txt()
            if 'volopts' in locals():
                v.addVolumetricData(cube, "cube", volopts)
            else:
                v.addVolumetricData(cube, "cube", {
                    'isoval': 300,
                    'color': "red",
                    'opacity': 0.95
                })
        v.zoomTo()
        v.show()

        return None
Ejemplo n.º 15
0
 def view(self):
     """
     A method designed to create a 3D figure of the AutoTST_Molecule with py3Dmol from the rdkit_molecule
     """
     mb = Chem.MolToMolBlock(self.rdkit_molecule)
     p = py3Dmol.view(width=600, height=600)
     p.addModel(mb, "sdf")
     p.setStyle({'stick': {}})
     p.setBackgroundColor('0xeeeeee')
     p.zoomTo()
     return p.show()
Ejemplo n.º 16
0
def vis_xyz(file_path):
    import py3Dmol
    with open(file_path) as f:
        xyz = f.read()

    xyzview = py3Dmol.view(width=400, height=400)
    xyzview.addModel(xyz, 'xyz')
    xyzview.setStyle({'stick': {}})
    xyzview.setBackgroundColor('0xeeeeee')
    xyzview.zoomTo()
    xyzview.show()
Ejemplo n.º 17
0
def _graph_conf(m, confId=0, energies=[]):
    mb = Chem.MolToMolBlock(m, confId=confId)
    p = py3Dmol.view(width=400, height=400)
    p.removeAllModels()
    p.addModel(mb, 'sdf')
    p.setStyle({'stick': {}})
    p.setBackgroundColor('0xeeeeee')
    p.zoomTo()
    if len(energies) > 0:
        print(
            f"G: {min(energies):.2f} + {energies[confId] - min(energies):.2f} kcal/mol"
        )
    return p.show()
Ejemplo n.º 18
0
def display_molecular(struc,
                      size=(600, 300),
                      supercell=(1, 1, 1),
                      axis=None,
                      animation=False,
                      interval=2000):
    """
    display the molecular crystals generated from pyxtal. If the animation is False, 
    only dump the structure to cif and let py3Dmol display it. If animation is on,
    show the generation of molecules in the crystal as an animation.

    Args:
        size: (width, height) in tuple
        supercell: replicate the crystal (valid only when animation is False)
        axis: 3-vector to reprent the rotational axis
        animation: whether or not display the animation

    Returns:
        py3Dmol object
    """

    (width, height) = size
    view = py3Dmol.view(height=height, width=width)
    if not animation:
        cif = struc.to_file()
        view.addModel(
            cif, 'cif', {
                'doAssembly': True,
                'duplicateAssemblyAtoms': True,
                'normalizeAssembly': True
            })
        view.setStyle({'stick': {'colorscheme': 'greenCarbon'}})
        view.addUnitCell()
        if axis is not None:
            site = struc.mol_sites[0]
            for id in range(len(site.wp)):
                mol = site.get_mol_object(id)
                addlines(view, mol.cart_coords.mean(axis=0), [axis.copy()])

        A, B, C = supercell
        view.replicateUnitCell(A, B, C)
    else:
        cifs = ""
        for i in range(len(struc.mol_sites[0].wp)):
            cifs += struc.to_file(sym_num=i + 1)
        view.addModelsAsFrames(cifs, 'cif')
        view.animate({'loop': 'forward', 'interval': interval})
        view.addUnitCell()
        view.setStyle({'model': 0}, {'stick': {'colorscheme': 'greenCarbon'}})
    return view.zoomTo()
Ejemplo n.º 19
0
 def draw_3d(self):
     try:
         import py3Dmol
         AllChem.EmbedMultipleConfs(self.rdkitmol_Hs)
         mb = Chem.MolToMolBlock(self.rdkitmol_Hs)
         p = py3Dmol.view(width=300,height=300)
         p.addModel(mb,'sdf')
         p.setStyle({'stick':{}})
         # Styles: stick, line, cross, sphere
         p.zoomTo()
         p.show()
         return p
     except:
         return 'py3Dmol and rdkit required'
Ejemplo n.º 20
0
    def view_ts(self, mol=None):
        """
        A method designed to create a 3D figure of the Multi_Molecule with py3Dmol
        """
        if not mol:
            mol = self.rdkit_ts

        mb = Chem.MolToMolBlock(mol)
        p = py3Dmol.view(width=400, height=400)
        p.addModel(mb, "sdf")
        p.setStyle({'stick': {}})
        p.setBackgroundColor('0xeeeeee')
        p.zoomTo()
        return p.show()
Ejemplo n.º 21
0
    def view3d(i=0):
        '''
        Simple structure viewer that uses py3Dmol to view PDB structure by
        indexing the list of PDBids

        Attributes:
            i (int): index of the protein if a list of PDBids
        '''

        print(f"PdbID: {pdbIds[i]}, Style: {style}")

        viewer = py3Dmol.view(query='pdb:' + pdbIds[i])
        viewer.setStyle({style: {'color': color}})

        return viewer.show()
Ejemplo n.º 22
0
def draw_all(rdmol):
    def draw_one(m, p, confId=-1):
        mb = Chem.MolToMolBlock(m, confId=confId)
        p.removeAllModels()
        p.addModel(mb, 'sdf')
        p.setStyle({'stick': {}})
        p.setBackgroundColor('0xeeeeee')
        p.zoomTo()
        return p.show()

    p = py3Dmol.view(width=400, height=400)
    interact(draw_one,
             m=fixed(rdmol),
             p=fixed(p),
             confId=(0, rdmol.GetNumConformers() - 1))
Ejemplo n.º 23
0
def draw_mols_surfs(mols,
                    width=400,
                    height=400,
                    surface=True,
                    surface_opacity=0.5):

    view = py3Dmol.view(width=width, height=height)
    view.setBackgroundColor('0xeeeeee')
    view.removeAllModels()
    for mol in mols:
        addMolToView(mol, view)
    if surface:
        view.addSurface(py3Dmol.SAS, {'opacity': surface_opacity})
    view.zoomTo()
    return view.show()
Ejemplo n.º 24
0
def jupyter_draw_conf(m, p=None, confId=-1, style='stick', extrastyle={}):
    """
    remember to
    from rdkit.Chem.Draw import IPythonConsole
    """
    mb = Chem.MolToMolBlock(m, confId=confId)

    if p is None:
        p = py3Dmol.view(width=400, height=400)
    p.removeAllModels()
    p.addModel(mb, 'sdf')
    p.setStyle({style: extrastyle})
    p.setBackgroundColor('0xeeeeee')
    p.zoomTo()
    return p.show()
Ejemplo n.º 25
0
    def show_xyz(self, width=600, height=600, print_xyz=False):
        """ Displays a 3D rendering of the conformer using Py3Dmol

        :param width: the width of the display window 
        :param height: the height of the display window
        """
        XYZ = "{0:3d}\n{1:s}\n".format(self.NAtoms, self._id)
        for at, xyz in zip(self.atoms, self.xyz):
            XYZ += "{0:3s}{1:10.3f}{2:10.3f}{3:10.3f}\n".format(
                at, xyz[0], xyz[1], xyz[2])
        xyzview = p3D.view(width=width, height=height)
        xyzview.addModel(XYZ, 'xyz')
        xyzview.setStyle({'stick': {}})
        xyzview.zoomTo()
        xyzview.show()
        if print_xyz == True: print(XYZ)
Ejemplo n.º 26
0
    def show(self, **kwargs):
        """
        Display 3Dmol.js output using IPython/Jupyter notebook display.

        If called with keyword arguments, those will be passed on to
        `update()`.

        """
        self.view = py3Dmol.view(width=self.width, height=self.height)
        for i, m in enumerate(self.models):
            m.add_to_view(self.view, i)
        self.view.zoomTo()
        self._set_hoverable()
        self.view.show()
        if len(kwargs) > 0:
            self.update(**kwargs)
Ejemplo n.º 27
0
def plot(smiles, size=(200, 200), style='stick'):
    """ 
    Visualize a molecule from its formula (smiles)
    Adapted from https://birdlet.github.io/2019/10/02/py3dmol_example 
    """
    mol = Chem.MolFromSmiles(smiles)
    mol = Chem.AddHs(mol)
    AllChem.EmbedMolecule(mol)
    AllChem.MMFFOptimizeMolecule(mol)
    block = Chem.MolToMolBlock(mol)

    viewer = py3Dmol.view(width=size[0], height=size[1])
    viewer.addModel(block, 'mol')
    viewer.setStyle({style: {}})
    viewer.zoomTo()
    viewer.show()
Ejemplo n.º 28
0
def draw(mol: Chem.Mol, energies: list = []) -> interact:
    """Make a drawing of all conformers in 3d

    :param mol: rdkit molecule
    :type mol: rdkit.Chem.Mol
    :param energies: list of conformer energies
    :type energies: list
    :return: interact 3D object
    """

    p = py3Dmol.view(width=400, height=400)
    return interact(_graph_conf,
                    m=fixed(mol),
                    p=fixed(p),
                    confId=[c.GetId() for c in mol.GetConformers()],
                    energies=fixed(energies))
Ejemplo n.º 29
0
def show_3D_mol(mol, confId):
    """
    Shows a molecule in 3D
    :param: an RDKit.mol
    :param confId: the IR of the conformer to show
    :return: molBlock
    """
    mb = Chem.MolToMolBlock(mol, confId=confId)

    p = py3Dmol.view()
    p.addModel(mb, 'sdf')
    p.setStyle({'stick': {}})
    p.setBackgroundColor('0xeeeeee')
    p.zoomTo()
    p.show()

    return mb
Ejemplo n.º 30
0
def drawMol3D(m, view=None, confId=-1, drawAs=None, bgColor=None, size=None):
    if bgColor is None:
        bgColor = bgcolor_3d
    if size is None:
        size = molSize_3d
    if view is None:
        view = py3Dmol.view(width=size[0], height=size[1])
    view.removeAllModels()

    try:
        ms = iter(m)
        for m in ms:
            addMolToView(m, view, confId, drawAs)
    except TypeError:
        addMolToView(m, view, confId, drawAs)
    view.setBackgroundColor(bgColor)
    view.zoomTo()
    return view.show()
Ejemplo n.º 31
0
    def show(
        self,
        *,
        style: Union[str, Dict[str, Any]] = "ball_and_stick",
        canvas: Tuple[int, int] = (400, 400)
    ) -> 'py3Dmol.view':
        """Creates a 3D representation of a moleucle that can be manipulated in Jupyter Notebooks and exported as images (`.png`).

        Parameters
        ----------
        style : Union[str, Dict[str, Any]], optional
            Either 'ball_and_stick' or 'stick' style representations or a valid py3Dmol style dictionary.
        canvas : Tuple[int, int], optional
            The (width, height) of the display canvas in pixels

        Returns
        -------
        py3Dmol.view
            A py3dMol view object of the molecule

        """
        if not which_import("py3Dmol", return_bool=True):
            raise ModuleNotFoundError(
                f"Python module py3DMol not found. Solve by installing it: `conda install -c conda-forge py3dmol`"
            )  # pragma: no cover

        import py3Dmol

        if isinstance(style, dict):
            pass
        elif style == 'ball_and_stick':
            style = {'stick': {'radius': 0.2}, 'sphere': {'scale': 0.3}}
        elif style == 'stick':
            style = {'stick': {}}
        else:
            raise KeyError(f"Style '{style}' not recognized.")

        xyzview = py3Dmol.view(width=canvas[0], height=canvas[1])

        xyzview.addModel(self.to_string("xyz", units="angstrom"), 'xyz')
        xyzview.setStyle(style)
        xyzview.zoomTo()
        return xyzview
Ejemplo n.º 32
0
def drawMol3D(m, view=None, confId=-1, drawAs=None, bgColor=None, size=None):
    if bgColor is None:
        bgColor = bgcolor_3d
    if size is None:
        size = molSize_3d
    if view is None:
        view = py3Dmol.view(width=size[0], height=size[1])
    view.removeAllModels()
    try:
        iter(m)
    except TypeError:
        addMolToView(m, view, confId, drawAs)
    else:
        ms = m
        for m in ms:
            addMolToView(m, view, confId, drawAs)

    view.setBackgroundColor(bgColor)
    view.zoomTo()
    return view.show()
Ejemplo n.º 33
0
def view3D(*alist, **kwargs):
    """Return a py3Dmol view instance for interactive visualization in
    Jupyter notebooks. Available arguments are: width, height (of
    the viewer), backgroundColor, zoomTo (a py3Dmol selection to center
    around), and style, which is a py3Dmol style object that will be
    applied to all atoms in the scene. More complex styling can be achieved
    by manipulating the view object directly.
    
    The default style is to show the protein in a rainbow cartoon and
    hetero atoms in sticks/spheres.
    
    GNM/ANM Coloring
    
    An array of fluctuation values (flucts) can be provided with the flucts kwarg
    for visualization of GNM/ANM calculations.  The array is assumed to 
    correpond to a calpha selection of the provided protein.
    The default color will be set to a RWB color scheme on a per-residue
    basis.  If the fluctuation vector contains negative values, the
    midpoint (white) will be at zero.  Otherwise the midpoint is the mean.
    
    An array of displacement vectors (vecs) can be provided with the vecs kwarg.
    The animation of these motions can be controlled with frames (number
    of frames to animate over), amplitude (scaling factor), and animate
    (3Dmol.js animate options).
    
    If multiple structures are provided with the flucts or vecs arguments, these
    arguments must be provided as lists of arrays of the appropriate dimension.
    """

    try:
        import py3Dmol
    except:
        raise ImportError('py3Dmol needs to be installed to use view3D')
    
    from .pdbfile import writePDBStream
    
    width = kwargs.get('width', 400)
    height = kwargs.get('height', 400)
    data_list = kwargs.pop('data', None)
    modes = kwargs.pop('mode', None)
    style = kwargs.pop('style', [])
    zoomto = kwargs.pop('zoomto', {})
    bgcolor = kwargs.pop('backgroundcolor', 'white')
    bgcolor = kwargs.pop('backgroundColor', bgcolor)
    frames = kwargs.pop('frames', 30)
    interval = kwargs.pop('interval', 1)
    anim = kwargs.pop('anim', False)
    scale = kwargs.pop('scale', 100)

    if modes is None:
        n_modes = 0
    else:
        modes = wrapModes(modes)
        n_modes = len(modes)

    if data_list is None:
        n_data = 0
    else:
        data_list = wrapModes(data_list)
        n_data = len(data_list)

    view = py3Dmol.view(width=width, height=height, js=kwargs.get('js','http://3dmol.csb.pitt.edu/build/3Dmol-min.js'))

    def _mapData(atoms, data):
        # construct map from residue to data property
        propmap = []
        for j, a in enumerate(atoms.calpha):
            propmap.append({'model': -1, 'chain': a.getChid(), 'resi': int(a.getResnum()), 
                            'props': {'data': float(data[j]) } })
        # set the atom property 
        # TODO: implement something more efficient on the 3Dmol.js side (this is O(n*m)!)
        view.mapAtomProperties(propmap)
        
        # color by property using gradient
        extreme = np.max(np.abs(data))
        lo = -extreme if np.min(data) < 0 else 0
        mid = np.mean(data) if np.min(data) >= 0 else 0
        view.setColorByProperty({'model': -1}, 'data', 'rwb', [extreme,lo,mid])
        view.setStyle({'model': -1},{'cartoon':{'style':'trace'}})    


    for i, atoms in enumerate(alist):
        pdb = createStringIO()
        writePDBStream(pdb, atoms)
        view.addAsOneMolecule(pdb.getvalue(), 'pdb')
        view.setStyle({'model': -1}, {'cartoon': {'color':'spectrum'}})
        view.setStyle({'model': -1, 'hetflag': True}, {'stick':{}})
        view.setStyle({'model': -1, 'bonds': 0}, {'sphere':{'radius': 0.5}})    

        if n_data:
            data = data_list[i]
            try:
                data = data.getArray()
            except AttributeError:
                pass

            if atoms.calpha.numAtoms() != len(data):
                raise RuntimeError("Atom count mismatch: {} vs {}. data styling assumes a calpha selection."
                                   .format(atoms.calpha.numAtoms(), len(data)))
            _mapData(atoms, data)
            
        if n_modes:
            mode = modes[i]
            try:
                arr = mode.getArray()
                is3d = mode.is3d()
            except AttributeError:
                arr = mode

            if is3d:
                if atoms.calpha.numAtoms()*3 != len(arr):
                    raise RuntimeError("Atom count mismatch: {} vs {}. mode animation assumes a calpha selection."
                                       .format(atoms.calpha.numAtoms(), len(arr)//3))

                if anim:
                    # construct map from residue to anm property and dx,dy,dz vectors
                    propmap = []
                    for j, a in enumerate(atoms.calpha):
                        propmap.append({'model': -1, 'chain': a.getChid(), 'resi': int(a.getResnum()),
                                        'props': {'dx': arr[3*j], 'dy': arr[3*j+1], 'dz': arr[3*j+2] } })
                    # set the atom property 
                    # TODO: implement something more efficient on the 3Dmol.js side (this is O(n*m)!)
                    view.mapAtomProperties(propmap)
                else:
                    for j, a in enumerate(atoms.calpha):
                        start = a._getCoords()
                        dcoords = arr[3*j:3*j+3]
                        end = start + dcoords * scale
                        view.addArrow({'start': {'x':start[0], 'y':start[1], 'z':start[2]},
                                       'end': {'x':end[0], 'y':end[1], 'z':end[2]},
                                       'radius': 0.3})
            else:
                if atoms.calpha.numAtoms() != len(arr):
                    raise RuntimeError("Atom count mismatch: {} vs {}. mode styling assumes a calpha selection."
                                       .format(atoms.calpha.numAtoms(), len(arr)))

                _mapData(atoms, arr)

                
    # setting styles ...
    view.setBackgroundColor(bgcolor)

    if n_modes:
        #create vibrations
        view.vibrate(frames, scale)
        
        animate = kwargs.get('animate', {'loop':'rock', 'interval':interval})
        view.animate(animate)     
        
    if isinstance(style, dict):
        style = ({}, style)
    if isinstance(style, tuple):
        styles = [style]
    else:
        styles = style
    for sel, style in styles:
        view.setStyle(sel, style)
        
    view.zoomTo(zoomto)
            
    return view
Ejemplo n.º 34
0
def view3D(*alist, **kwargs):
    """Return a py3Dmol view instance for interactive visualization in
    Jupyter notebooks. Available arguments are: width, height (of
    the viewer), backgroundColor, zoomTo (a py3Dmol selection to center
    around), and style, which is a py3Dmol style object that will be
    applied to all atoms in the scene. More complex styling can be achieved
    by manipulating the view object directly.
    
    The default style is to show the protein in a rainbow cartoon and
    hetero atoms in sticks/spheres.
    
    GNM/ANM Coloring
    
    An array of fluctuation values can be provided with the flucts kwarg
    for visualization of GNM/ANM calculations.  The array is assumed to 
    correpond to a calpha selection of the provided protein.
    The default color will be set to a RWB color scheme on a per-residue
    basis.  If the fluctuation vector contains negative values, the
    midpoint (white) will be at zero.  Otherwise the midpoint is the mean.
    
    An array of displacement vectors can be provided with the vecs kwarg.
    The animation of these motions can be controlled with frames (number
    of frames to animate over), amplitude (scaling factor), and animate
    (3Dmol.js animate options).
    """
    import StringIO, py3Dmol
    from pdbfile import writePDBStream
    
    pdb = StringIO.StringIO()
    
    for atoms in alist:
        writePDBStream(pdb, atoms)
    
    width = kwargs.get('width',400)
    height = kwargs.get('height',400)
    view = py3Dmol.view(width=width,height=height,js=kwargs.get('js','http://3dmol.csb.pitt.edu/build/3Dmol-min.js'))
    
    #case insensitive kwargs..
    bgcolor = kwargs['backgroundcolor'] if 'backgroundcolor' in kwargs else kwargs.get('backgroundColor','white')
    view.setBackgroundColor(bgcolor)
    view.addModels(pdb.getvalue(),'pdb')
    view.setStyle({'cartoon': {'color':'spectrum'}})
    view.setStyle({'hetflag': True}, {'stick':{}})
    view.setStyle({'bonds': 0}, {'sphere':{'radius': 0.5}})    

    if 'flucts' in kwargs:
        garr = kwargs['flucts']
        #note we are only getting info from last set of atoms..
        if atoms.calpha.numAtoms() != len(garr):
            raise RuntimeError("Atom count mismatch: {} vs {}.  flucts styling assume a calpha selection.".format(atoms.calpha.numAtoms(), len(garr)))
        else:
            #construct map from residue to flucts property
            propmap = []
            for (i,a) in enumerate(atoms.calpha):
                propmap.append({'chain': a.getChid(), 'resi':a.getResnum(), 'props': {'flucts': garr[i] } })
            #set the atom property 
            #TODO: implement something more efficient on the 3Dmol.js side (this is O(n*m)!)
            view.mapAtomProperties(propmap)
            
            #color by property using gradient
            extreme = np.abs(garr).max()
            lo = -extreme if garr.min() < 0 else 0
            mid = np.mean(garr) if garr.min() >= 0 else 0
            view.setColorByProperty({}, 'flucts', 'rwb', [extreme,lo,mid])
            view.setStyle({'cartoon':{'style':'trace'}})
            
    if 'vecs' in kwargs:
        aarr = kwargs['vecs']  #has xyz coordinates

        #note we are only getting info from last set of atoms..
        if atoms.calpha.numAtoms()*3 != len(aarr):
            raise RuntimeError("Atom count mismatch: {} vs {}.  vecs animation assume a calpha selection.".format(atoms.calpha.numAtoms(), len(aarr)/3))
        else:
            #construct map from residue to anm property and dx,dy,dz vectors
            propmap = []
            for (i,a) in enumerate(atoms.calpha):
                propmap.append({'chain': a.getChid(), 'resi':a.getResnum(),
                    'props': {'dy': aarr[3*i+1], 'dz': aarr[3*i+2] } });
            #set the atom property 
            #TODO: implement something more efficient on the 3Dmol.js side (this is O(n*m)!)
            view.mapAtomProperties(propmap)
            
            #create vibrations
            frames = kwargs.get('frames',10)
            amplitude = kwargs.get('amplitude',100)
            view.vibrate(frames, amplitude)
            
            animate = kwargs.get('animate',{'loop':'rock'})
            view.animate(animate)                

    if 'style' in kwargs: # this is never a list
        view.setStyle({},kwargs['style'])
        
    if 'styles' in kwargs:
        #allow simpler forms - convert them into a list
        styles = kwargs['styles']
        if type(styles) == dict:
            styles = ({},styles)
        if type(styles) == tuple:
            styles = [styles]
        for (sel, style) in styles:
            view.setStyle(sel, style)
    
    zoomto = kwargs['zoomto'] if 'zoomto' in kwargs else kwargs.get('zoomTo',{})
    view.zoomTo(zoomto)
            
    return view