Beispiel #1
0
def MolToJSON(mol, size=(300,300), kekulize=True, wedgeBonds=True,
               fitImage=False, options=None, **kwargs):
  if not mol:
    raise ValueError,'Null molecule provided'

  canvas = Canvas(size=size)

  if options is None:
    options = DrawingOptions()
  if fitImage:
      options.dotsPerAngstrom = int(min(size) / 10)
  options.wedgeDashedBonds = wedgeBonds
  try:
    drawer = MolDrawing(canvas=canvas,drawingOptions=options)
  except TypeError:
    drawer = MolDrawing(canvas=canvas)

  if kekulize:
    mol = Chem.Mol(mol.ToBinary())
    Chem.Kekulize(mol)

  if not mol.GetNumConformers():
    Compute2DCoords(mol)

  drawer.AddMol(mol,**kwargs)
  try:
    drawer.AddLegend(kwargs.get('legend', ''))
  except AttributeError:
    pass

  canvas.flush()
  return canvas.json

#------------------------------------------------------------------------------
Beispiel #2
0
def _parseMolData(data):
    """Imports a molfile and verifies if all of the coordinates are set to zeros.
    if they are set to zeros then we know there are no real coordinates in the molfile
    In this case we allow RDKit to recaculate the positions of the atoms and come up with its own pictorial representation of the molecule
    If not we use the molecule as drawn"""
    suppl = SDMolSupplier()

    suppl.SetData(str(data), sanitize=False)
    data = [x for x in suppl if x]
    for x in data:
        if not x.HasProp("_drawingBondsWedged"):
            SanitizeMol(x)
        ctab = MolToMolBlock(x)
        ctablines = [
            item.split("0.0000") for item in ctab.split("\n")
            if "0.0000" in item
        ]
        needs_redraw = 0
        for line in ctablines:
            if len(line) > 3:
                needs_redraw += 1
        if needs_redraw == len(ctablines):
            #check for overlapping molecules in the CTAB
            SanitizeMol(x)
            Compute2DCoords(x)
    return data
Beispiel #3
0
def annotate_chemical_svg(network):
    """Annotate chemical nodes with SVGs depiction.

    :param network: dict, network of elements as outputted by the sbml_to_json method
    :return: dict, network annotated
    """
    from rdkit.Chem import MolFromInchi
    from rdkit.Chem.Draw import rdMolDraw2D
    from rdkit.Chem.AllChem import Compute2DCoords
    from urllib import parse

    for node in network['elements']['nodes']:
        if node['data']['type'] == 'chemical' and node['data'][
                'inchi'] is not None:
            inchi = node['data']['inchi']
            try:
                mol = MolFromInchi(inchi)
                # if mol is None:
                #     raise BaseException('Mol is None')
                Compute2DCoords(mol)
                drawer = rdMolDraw2D.MolDraw2DSVG(200, 200)
                drawer.DrawMolecule(mol)
                drawer.FinishDrawing()
                svg_draft = drawer.GetDrawingText().replace("svg:", "")
                svg = 'data:image/svg+xml;charset=utf-8,' + parse.quote(
                    svg_draft)
                node['data']['svg'] = svg
            except BaseException as e:
                msg = 'SVG depiction failed from inchi: "{}"'.format(inchi)
                logging.warning(msg)
                logging.warning("Below the RDKit backtrace...")
                logging.warning(e)
                node['data']['svg'] = None

    return network
Beispiel #4
0
    def update_mol_image(self, mol_name, save=False, verbosity=0):
        """ Generate mol images, if needed

        :param str mol_name: name of the molecule to be updated
        :param bool save: automatically save data
        :param int verbosity: controls verbosity level
        """

        import rdkit.Chem
        from rdkit.Chem.Draw import MolDraw2DSVG
        from rdkit.Chem.AllChem import Compute2DCoords

        this_mol = self.ligands_data[mol_name]['molecule']
        self.ligands_data[mol_name].setdefault('images', {})

        if not {'2d_hs', '2d_nohs'}.issubset(
                self.ligands_data[mol_name]['images']):
            draw_2d_svg = MolDraw2DSVG(300, 300)
            temp_mol = rdkit.Chem.Mol(this_mol)
            Compute2DCoords(temp_mol)
            draw_2d_svg.drawOptions().addStereoAnnotation = True
            draw_2d_svg.DrawMolecule(temp_mol)
            draw_2d_svg.FinishDrawing()
            svg_data_hs = draw_2d_svg.GetDrawingText()

            temp_mol = rdkit.Chem.RemoveHs(temp_mol)
            Compute2DCoords(temp_mol)
            draw_2d_svg = MolDraw2DSVG(300, 300)
            draw_2d_svg.DrawMolecule(temp_mol)
            draw_2d_svg.FinishDrawing()
            svg_data_no_hs = draw_2d_svg.GetDrawingText()

            self.ligands_data[mol_name]['images'].update({
                '2d_hs':
                svg_data_hs,
                '2d_nohs':
                svg_data_no_hs
            })

        if save:
            self.save_data()
Beispiel #5
0
    def toDataFrame(self, fields=None, molAsImage=True, sketch=True):
        """
        Returns a pandas.DataFrame of the SmallMolLib object.

        Parameters
        ----------
        fields: list
            The list of fields to convert into a pandas DataFrame column
        molAsImage: bool
            If True, the rdkit.Chem.rdchem.Mol is converted into an image
        sketch: bool
            If True, the molecule are rendered to be 2D

        Returns
        -------
        dataframe: pandas.DataFrame
            The pandas DataFrame
        """
        from rdkit.Chem import PandasTools
        from rdkit.Chem.AllChem import Compute2DCoords
        import pandas as pd
        from copy import deepcopy

        if fields is not None:
            if not isinstance(fields, list):
                raise TypeError(
                    'The argument fields passed {} should be a list '.format(
                        type(fields)))
        else:
            fields = ['ligname', '_mol'] if molAsImage else ['ligname']

        records = []
        indexes = []
        for i, m in enumerate(self._mols):
            row = dict((f, m.__getattribute__(f)) for f in fields)
            if sketch:
                mm = deepcopy(m._mol)
                Compute2DCoords(mm)
                row['_mol'] = mm
            records.append(row)
            indexes.append(i)

        df = pd.DataFrame(records, columns=fields, index=indexes)
        if molAsImage:
            Chem.PandasTools.ChangeMoleculeRendering(df)
        return df
 def testMakePNG(self):
     # smoke test only--that it doesn't fail, not that it looks correct (that's outside the scope of this package)
     # The choices shown resulted (at last check) in 3 fragments, one of which has a branch
     try:
         silent_remove(TEST_PNG)
         result = create_sample_kmc_result(num_initial_monos=24, max_monos=24, seed=1, max_time=SHORT_TIME)
         summary = analyze_adj_matrix(result[ADJ_MATRIX])
         adj_analysis_to_stdout(summary, break_co_bonds=False)
         nodes = result[MONO_LIST]
         adj = result[ADJ_MATRIX]
         block = generate_mol(adj, nodes)
         mol = MolFromMolBlock(block)
         Compute2DCoords(mol)
         MolToFile(mol, TEST_PNG, size=(2000, 1200))
         self.assertTrue(os.path.isfile(TEST_PNG))
     finally:
         silent_remove(TEST_PNG, disable=DISABLE_REMOVE)
         pass
Beispiel #7
0
 def display_smiles(smiles_list,colour_type,params,molSize=(450,150)):
     for smile in smiles_list:
         highlight =[]
         colors={}
         highlightBonds=[]
         highlightAtomRadii ={}
         bond_colors={}
         mol = smile_to_mol(smile, params)
         mol = Chem.RemoveHs(mol,sanitize = False)
         if(colour_type=='t'):
             color = (1,1,0.925)
         elif(colour_type=='g'):
             
             color = (0.925,1,0.925)
         elif(colour_type=='w'):
             color = (1,1,1)
         else:
             color = (0.925,0.925,1)
         
             
         for i in range(mol.GetNumAtoms()):
             highlight.append(i)
             colors[i] = color
             highlightAtomRadii[i] =1000000
             
             
         for i in range(mol.GetNumBonds()):
             highlightBonds.append(i)
             bond_colors[i] = color
 
         
         Compute2DCoords(mol)
         drawer = rdMolDraw2D.MolDraw2DCairo(molSize[0],molSize[1])
         drawer.DrawMolecule(mol,highlightAtoms=highlight,highlightAtomColors=colors,highlightBonds=highlightBonds,highlightBondColors=bond_colors,highlightAtomRadii=highlightAtomRadii)
 
         drawer.FinishDrawing()
         fp = BytesIO()
         #with open(fp,'wb') as f:
         fp.write(drawer.GetDrawingText())
         
         
         img_top = PIL.Image.open(fp)
         display(img_top)
Beispiel #8
0
def get_batch_from_xls_row(index, row, structure_col, project):
    if structure_col:
        smiles_str = row[structure_col]
        try:
            struc = Chem.MolFromSmiles(smiles_str)
            if struc:
                Compute2DCoords(struc)
                b = CBHCompoundBatch.objects.from_rd_mol(struc,
                                                         smiles=smiles_str,
                                                         project=project,
                                                         reDraw=True)
                b.blinded_batch_id = None
            else:
                raise Exception("Smiles not processed")

        except Exception, e:
            b = CBHCompoundBatch.objects.blinded(project=project)
            b.original_smiles = smiles_str
            b.warnings["parseerror"] = "true"
            b.properties["action"] = "Ignore"
Beispiel #9
0
def produce_output(adj_matrix, mono_list, cfg):
    if cfg[SUPPRESS_SMI] and not (cfg[SAVE_JSON] or cfg[SAVE_PNG] or cfg[SAVE_SVG]):
        format_list = [SAVE_TCL]
        mol = None  # Make IDE happy
    else:
        # Default out is SMILES, which requires getting an rdKit molecule object; also required for everything
        #    except the TCL format
        format_list = [SAVE_TCL, SAVE_JSON, SAVE_PNG, SAVE_SVG]
        block = generate_mol(adj_matrix, mono_list)
        mol = MolFromMolBlock(block)
        try:
            smi_str = MolToSmiles(mol) + '\n'
        except:
            raise InvalidDataError("Error in producing SMILES string.")
        # if SMI is to be saved, don't output to stdout
        if cfg[SAVE_SMI]:
            fname = create_out_fname(cfg[BASENAME], base_dir=cfg[OUT_DIR], ext=SAVE_SMI)
            str_to_file(smi_str, fname, print_info=True)
        else:
            print("\nSMILES representation: \n", MolToSmiles(mol), "\n")
        if cfg[SAVE_PNG] or cfg[SAVE_SVG] or cfg[SAVE_JSON]:
            # PNG and SVG make 2D images and thus need coordinates
            # JSON will save coordinates--zero's if not computed; might as well compute and save non-zero values
            Compute2DCoords(mol)

    for save_format in format_list:
        if cfg[save_format]:
            fname = create_out_fname(cfg[BASENAME], base_dir=cfg[OUT_DIR], ext=save_format)
            if save_format == SAVE_TCL:
                gen_tcl(adj_matrix, mono_list, tcl_fname=fname, chain_id=cfg[CHAIN_ID],
                        psf_fname=cfg[PSF_FNAME], toppar_dir=cfg[TOPPAR_DIR], out_dir=cfg[OUT_DIR])
            if save_format == SAVE_JSON:
                json_str = MolToJSON(mol)
                str_to_file(json_str + '\n', fname)
            elif save_format == SAVE_PNG or save_format == SAVE_SVG:
                MolToFile(mol, fname, size=cfg[IMAGE_SIZE])
            print(f"Wrote file: {fname}")
Beispiel #10
0
    def depict(self, sketch=True, filename=None, ipython=False, optimize=False, optimizemode='std', removeHs=True,
               atomlabels=None, highlightAtoms=None, resolution=(400, 200)):
        """
        Depicts the molecules. It is possible to save it into an svg file and also generates a jupiter-notebook rendering

        Parameters
        ----------
        sketch: bool
            Set to True for 2D depiction
        filename: str
            Set the filename for the svg file
        ipython: bool
            Set to True to return the jupiter-notebook rendering
        optimize: bool
            Set to True to optimize the conformation. Works only with 3D.
        optimizemode: ['std', 'mmff']
            Set the optimization mode for 3D conformation
        removeHs: bool
            Set to True to hide hydrogens in the depiction
        atomlabels: str
            Accept any combinations of the following pararemters as unique string '%a%i%c%*' a:atom name, i:atom index,
            c:atom formal charge (+/-), *:chiral (* if atom is chiral)
        highlightAtoms: list
            List of atom to highlight. It can be also a list of atom list, in this case different colors will be used
        resolution: tuple of integers
            Resolution in pixels: (X, Y)

        Returns
        -------
            ipython_svg: SVG object if ipython is set to True

        Example
        -------
        >>> sm.depict(ipython=True, optimize=True, optimizemode='std')  # doctest: +SKIP
        >>> sm.depict(ipython=True, sketch=True)  # doctest: +SKIP
        >>> sm.depict(ipython=True, sketch=True)  # doctest: +SKIP
        >>> sm.depict(ipython=True, sketch=True, atomlabels="%a%i%c")  # doctest: +SKIP
        >>> ids = np.intersect1d(sm.get('idx', 'hybridization SP2'), sm.get('idx', 'element C'))  # doctest: +SKIP
        >>> sm.depict(ipython=True, sketch=True,highlightAtoms=ids.tolist(), removeHs=False)  # doctest: +SKIP
        """
        from rdkit import Chem
        from rdkit.Chem.AllChem import Compute2DCoords, EmbedMolecule, MMFFOptimizeMolecule, ETKDG
        from copy import deepcopy

        if sketch and optimize:
            raise ValueError('Impossible to use optimization in  2D sketch representation')

        if optimizemode not in ['std', 'mmff']:
            raise ValueError('Optimization mode {} not understood. Can be "std" or "ff"'.format(optimizemode))

        elements = self._element
        indexes = self._idx
        formalcharges = self._formalcharge
        chirals = self._chiral

        _mol = deepcopy(self._mol)

        if sketch:
            Compute2DCoords(_mol)

        if removeHs:
            _mol = Chem.RemoveHs(_mol)
            elements = self.get('element', 'element H', invert=True)
            indexes = self.get('idx', 'element H', invert=True)
            formalcharges = self.get('formalcharge', 'element H', invert=True)
            chirals = self.get('chiral', 'element H', invert=True)

        _labelsFunc = ['a', 'i', 'c', '*']

        if atomlabels is not None:
            labels = atomlabels.split('%')[1:]
            formalcharges = ['' if c == 0 else "+" if c == 1 else "-" for c in formalcharges]
            chirals = ['' if c == '' else '*' for c in chirals]
            values = [elements, indexes, formalcharges, chirals]

            idxs = [_labelsFunc.index(l) for l in labels]
            labels_required = [values[i] for i in idxs]
            atomlabels = ["".join([str(i) for i in a]) for a in list(zip(*labels_required))]

        if optimize:
            if optimizemode == 'std':
                EmbedMolecule(_mol, ETKDG())
            elif optimizemode == 'mmff':
                MMFFOptimizeMolecule(_mol)

        return _depictMol(_mol, filename=filename, ipython=ipython,  atomlabels=atomlabels,
                          highlightAtoms=highlightAtoms, resolution=resolution)
def _computeCoords(mol, force=False):
    if force or (not mol.GetNumConformers() or mol.GetConformer().Is3D()):
        Compute2DCoords(mol)
    return mol
Beispiel #12
0
    def post_validate_list(self, request, **kwargs):
        """
        When a list of SMILES patterns are submitted, save them to elasticsearhc and
        call the normal validate multi batch function to give the normal statistics page
        """
        session_key = request.COOKIES[settings.SESSION_COOKIE_NAME]
        deserialized = self.deserialize(request,
                                        request.body,
                                        format=request.META.get(
                                            'CONTENT_TYPE',
                                            'application/json'))

        deserialized = self.alter_deserialized_detail_data(
            request, deserialized)
        bundle = self.build_bundle(data=dict_strip_unicode_keys(deserialized),
                                   request=request)
        if bundle.obj.pk:
            self.authorized_update_detail(self.get_object_list(bundle.request),
                                          bundle)
        else:
            self.authorized_create_detail(self.get_object_list(bundle.request),
                                          bundle)
        smilesdata = bundle.data.get("smilesdata", "")
        objects = [smi.strip() for smi in smilesdata.splitlines(True)]
        batches = []
        # first assume smiles
        allmols = [(obj, Chem.MolFromSmiles(str(obj))) for obj in objects]
        # Next test for inchi
        multiple_batch = CBHCompoundMultipleBatch.objects.create(
            project=bundle.data["project"], batch_count=len(allmols))
        for index, m in enumerate(allmols):
            if m[1] is None:
                inchimol = Chem.MolFromInchi(
                    str(m[0].encode('ascii', 'ignore')))
                if inchimol is not None:
                    allmols[index] = (Chem.MolToSmiles(inchimol), inchimol)
        for m in allmols:
            if (m[1]):
                Compute2DCoords(m[1])
        batches = []

        for mol2 in allmols:
            if mol2[1]:
                b = CBHCompoundBatch.objects.from_rd_mol(
                    mol2[1],
                    smiles=mol2[0],
                    project=bundle.data["project"],
                    reDraw=True)
            else:
                b = CBHCompoundBatch.objects.blinded(
                    project=bundle.data["project"])
                b.warnings["smilesParseError"] = "true"
                b.properties["action"] = "Ignore"
                b.original_smiles = mol2[0]
            b.multiple_batch_id = multiple_batch.pk
            b.created_by = bundle.request.user.username
            b.created_by_id = bundle.request.user.id
            batches.append(b)

        bundle.data["current_batch"] = multiple_batch.pk
        bundle.data["headers"] = []
        validate_multi_batch(self, multiple_batch, bundle.data, session_key,
                             batches)
        return self.create_response(request,
                                    bundle,
                                    response_class=http.HttpAccepted)
Beispiel #13
0
def display_encoded_decoded(params,tanimoto_values,encode_decode_mols,num_F2=100,pic_size=(1190/2,1684/2),start_num=1):
    

    text_size =12
    text_font_size = 12

    
    orange = (255/255,165/255,0)
    green = (0,1,0)
    light_blue = (0,1,1)

    png_files =[]

    w_len = 1 
    '''
    stop_while = True
    while stop_while:
        
        h_len_min = int(num_F2/w_len)+int(np.mod(num_F2,w_len)>0)
        
        h_temp = pic_size[0]/w_len*h_len_min
        if(h_temp>pic_size[1]) :
            w_len = w_len+1
        else:
            stop_while = False
    '''
    w_len = 5
    h_len_min = int(num_F2/w_len)+int(np.mod(num_F2,w_len)>0)

    h_len =  h_len_min
    molSize= (int(pic_size[0]/w_len)*2,int(pic_size[0]/w_len))
    
    x = np.array(range(len(libExamples)))
    #random.shuffle(x)
    for mol_idx1 in range(h_len*w_len):
       
        
        if( mol_idx1 < num_F2):
            #mol = Chem.RemoveHs(mol,sanitize = False)


            mol = Chem.RemoveHs(encode_decode_mols[mol_idx1][0],sanitize = False)
            Compute2DCoords(mol)
            drawer = rdMolDraw2D.MolDraw2DCairo(molSize[0],int(molSize[1]/2)*2)
            drawer.DrawMolecule(mol)
            drawer.FinishDrawing()
            fp = BytesIO()
            #with open(fp,'wb') as f:
            fp.write(drawer.GetDrawingText())
            img_top = PIL.Image.open(fp)
            
            mol = Chem.RemoveHs(encode_decode_mols[mol_idx1][1],sanitize = False)
            Compute2DCoords(mol)
            drawer = rdMolDraw2D.MolDraw2DCairo(molSize[0],int(molSize[1]/2)*2)
            drawer.DrawMolecule(mol)
            drawer.FinishDrawing()
            fp = BytesIO()
            #with open(fp,'wb') as f:
            fp.write(drawer.GetDrawingText())
            
            
            img_bottom = PIL.Image.open(fp)
            

            text_works = Image.new('RGB', (molSize[0],text_size), color = (255, 255, 255))
            d = ImageDraw.Draw(text_works)

            
            d.text((0,0),str(mol_idx1+start_num), font=ImageFont.truetype("arialbd.ttf", text_font_size),fill=(0,0,0))
            d.text((0,0),'              Tanimoto '+str(int(tanimoto_values[mol_idx1]*100)/100), font=ImageFont.truetype("arial.ttf", text_font_size),fill=(0,0,0))

            
            comb_img = vstack_img(text_works,vstack_img(img_top,img_bottom))
            fp1 = BytesIO()
            comb_img.save(fp1, 'PNG')
            png_files.append(fp1)
            #display(comb_img)
            #print(comb_img.size)
            '''
            img, svg = gen_img_svg_mol(mol,molSize=(500,250))
            fp = BytesIO()
            
            display(img)
            print(libExamples['smiles'][mol_idx])
            svg2png(bytestring=svg,write_to=fp,scale=1)
            
                text_selected_frags_flash = Image.new('RGB', (half_pic_size[0],single_space*2), color = (255, 255, 255))
    d = ImageDraw.Draw(text_selected_frags_flash)
    d.text((0,0), "Bag of sampled first order fragments", font=ImageFont.truetype("arial.ttf", font_size),fill=(0,0,0))
    d.text((0,single_space), "Status: Sampling node", font=ImageFont.truetype("arial.ttf", font_size),fill=(0,0,0))
            
            '''
            
        else:
            fp2 = BytesIO()
            png_files.append(fp2)
            
            #print((int(molSize[1]/2.0)*4))
            image = Image.new('RGB', (molSize[0],(int(molSize[1]/2.0)*4)+text_size), color = 'white')
            draw = ImageDraw.Draw(image)
            image.save(fp2, 'PNG')
            #print(image.size)
            
    imgs = [ PIL.Image.open(i) for i in png_files ]

    imgs_comb = []
    for y_idx in range(0,h_len):
        y_idx_list = png_files[y_idx*w_len:w_len+y_idx*w_len]
        imgs_comb.append( np.hstack( (np.asarray(PIL.Image.open(i) ) for i in y_idx_list ) ))
        
    imgs_comb = np.vstack(imgs_comb)
    
    imgs_comb = PIL.Image.fromarray( imgs_comb)
    imgs_comb_size = imgs_comb.size
    '''
    if(imgs_comb_size[0]!=pic_size[0]):
        fp = BytesIO()
        image = Image.new('RGB', (pic_size[0]-imgs_comb_size[0],imgs_comb_size[1]), color = 'white')
        draw = ImageDraw.Draw(image)
        image.save(fp, 'PNG')
        imgs_comb=( np.hstack( (np.asarray(i) for i in [imgs_comb,PIL.Image.open(fp)] ) ))
        
        imgs_comb = PIL.Image.fromarray( imgs_comb)
        imgs_comb_size = imgs_comb.size
    '''
    '''
    if(imgs_comb_size[1]!=pic_size[1]):
        fp = BytesIO()
        image = Image.new('RGB', (pic_size[0],pic_size[1]-imgs_comb_size[1]), color = 'white')
        draw = ImageDraw.Draw(image)
        image.save(fp, 'PNG')
        imgs_comb=( np.vstack( (np.asarray(i) for i in [imgs_comb,PIL.Image.open(fp)] ) ))
        imgs_comb = PIL.Image.fromarray( imgs_comb)
    '''
    fp = BytesIO()
    imgs_comb.save( fp,'PNG' )
    
    return imgs_comb
Beispiel #14
0
def display_training_data(params,num_F2=80,pic_size=(int(1190*0.9),int(1684*0.9)),train=True):
    text_size =20
    text_font_size = 20
    if(train==True):
        libExamples = pd.read_csv(params['model_dir']+'Experimental_Training_set_NN.csv')
        libExamples = libExamples.reset_index(drop=True)
    else:
        libExamples = pd.read_csv(params['model_dir']+'Experimental_Test_NN.csv')
        libExamples = libExamples.reset_index(drop=True)
    
    
    orange = (255/255,165/255,0)
    green = (0,1,0)
    light_blue = (0,1,1)

    png_files =[]

    w_len = 1 
    stop_while = True
    while stop_while:
        
        h_len_min = int(num_F2/w_len)+int(np.mod(num_F2,w_len)>0)
        
        h_temp = pic_size[0]/w_len*h_len_min
        if(h_temp>pic_size[1]) :
            w_len = w_len+1
        else:
            stop_while = False
    h_len =  h_len_min
    molSize= (int(pic_size[0]/w_len),int(pic_size[0]/w_len))
    
    x = np.array(range(len(libExamples)))
    #random.shuffle(x)
    for mol_idx1 in range(h_len*w_len):
       
        
        if( mol_idx1 < num_F2):
            mol_idx = x[mol_idx1]
            highlight =[]
            colors={}
            highlightBonds=[]
            highlightAtomRadii ={}
            bond_colors={}
            mol =smile_to_mol(libExamples['smiles'][mol_idx], params)
            mol = Chem.RemoveHs(mol,sanitize = False)
            if(libExamples['metrics'][mol_idx]==1):
                for i in range(mol.GetNumAtoms()):
                    highlight.append(i)
                    if(libExamples['metrics'][mol_idx]==1):
                        colors[i] = (0.75,1,0.75)
                    else:
                        colors[i] = (1,0.75,0.75)
                    highlightAtomRadii[i] =1000000
                        
                for i in range(mol.GetNumBonds()):
                    highlightBonds.append(i)
                    if(libExamples['metrics'][mol_idx]==1):
                        bond_colors[i] = (0.75,1,0.75)
                    else:
                        bond_colors[i] = (1,0.75,0.75)

            
            Compute2DCoords(mol)
            drawer = rdMolDraw2D.MolDraw2DCairo(molSize[0],molSize[1])
            drawer.DrawMolecule(mol,highlightAtoms=highlight,highlightAtomColors=colors,highlightBonds=highlightBonds,highlightBondColors=bond_colors,highlightAtomRadii=highlightAtomRadii)

            drawer.FinishDrawing()
            fp = BytesIO()
            #with open(fp,'wb') as f:
            fp.write(drawer.GetDrawingText())
            
            
            img_top = PIL.Image.open(fp)
            if(libExamples['metrics'][mol_idx]==1):
                text_works = Image.new('RGB', (molSize[0],text_size), color = (191,255,191))
            else:
                text_works = Image.new('RGB', (molSize[0],text_size), color = (255, 255, 255))
            d = ImageDraw.Draw(text_works)

            if((libExamples['ECFP'][mol_idx]==0 and libExamples['metrics'][mol_idx]==1)or(libExamples['ECFP'][mol_idx]==1 and libExamples['metrics'][mol_idx]==0)):
                symbol = 'E'
            else:
                symbol =  ""
            d.text((int(molSize[0]/2)+text_size*0.5,0), symbol, font=ImageFont.truetype("arial.ttf", text_font_size),fill=(0,0,255))
            
            if((libExamples['ChemVAE'][mol_idx]==0 and libExamples['metrics'][mol_idx]==1)or(libExamples['ChemVAE'][mol_idx]==1 and libExamples['metrics'][mol_idx]==0)):
                symbol =  'C'
            else:
                symbol =  ""
            d.text((int(molSize[0]/2)+text_size*1.5,0), symbol, font=ImageFont.truetype("arial.ttf", text_font_size),fill=(0,0,255))
            
            if((libExamples['rnd_FragVAE'][mol_idx]==0 and libExamples['metrics'][mol_idx]==1)or(libExamples['rnd_FragVAE'][mol_idx]==1 and libExamples['metrics'][mol_idx]==0)):
                symbol =  'R'
            else:
                symbol =  ""
            d.text((int(molSize[0]/2)-text_size*0.5,0), symbol, font=ImageFont.truetype("arial.ttf", text_font_size),fill=(0,0,255))
            
            if((libExamples['FragVAE'][mol_idx]==0 and libExamples['metrics'][mol_idx]==1)or(libExamples['FragVAE'][mol_idx]==1 and libExamples['metrics'][mol_idx]==0)):
                symbol =  'F'
            else:
                symbol =  ""
            d.text((int(molSize[0]/2)-text_size*1.5,0),symbol, font=ImageFont.truetype("arial.ttf", text_font_size),fill=(0,0,255))
            d.text((0,0),str(mol_idx1+1), font=ImageFont.truetype("arialbd.ttf", text_font_size),fill=(0,0,0))


            
            comb_img = vstack_img(img_top,text_works)
            fp1 = BytesIO()
            comb_img.save(fp1, 'PNG')
            png_files.append(fp1)
 
            '''
            img, svg = gen_img_svg_mol(mol,molSize=(500,250))
            fp = BytesIO()
            
            display(img)
            print(libExamples['smiles'][mol_idx])
            svg2png(bytestring=svg,write_to=fp,scale=1)
            
                text_selected_frags_flash = Image.new('RGB', (half_pic_size[0],single_space*2), color = (255, 255, 255))
    d = ImageDraw.Draw(text_selected_frags_flash)
    d.text((0,0), "Bag of sampled first order fragments", font=ImageFont.truetype("arial.ttf", font_size),fill=(0,0,0))
    d.text((0,single_space), "Status: Sampling node", font=ImageFont.truetype("arial.ttf", font_size),fill=(0,0,0))
            
            '''
            
        else:
            fp2 = BytesIO()
            png_files.append(fp2)
            

            image = Image.new('RGB', (molSize[0],molSize[1]+text_size), color = 'white')
            draw = ImageDraw.Draw(image)
            image.save(fp2, 'PNG')
            
    imgs = [ PIL.Image.open(i) for i in png_files ]

    imgs_comb = []
    for y_idx in range(0,h_len):
        y_idx_list = png_files[y_idx*w_len:w_len+y_idx*w_len]
        imgs_comb.append( np.hstack( (np.asarray(PIL.Image.open(i) ) for i in y_idx_list ) ))
        
    imgs_comb = np.vstack(imgs_comb)
    
    imgs_comb = PIL.Image.fromarray( imgs_comb)
    imgs_comb_size = imgs_comb.size
    if(imgs_comb_size[0]!=pic_size[0]):
        fp = BytesIO()
        image = Image.new('RGB', (pic_size[0]-imgs_comb_size[0],imgs_comb_size[1]), color = 'white')
        draw = ImageDraw.Draw(image)
        image.save(fp, 'PNG')
        imgs_comb=( np.hstack( (np.asarray(i) for i in [imgs_comb,PIL.Image.open(fp)] ) ))
        
        imgs_comb = PIL.Image.fromarray( imgs_comb)
        imgs_comb_size = imgs_comb.size
    '''
    if(imgs_comb_size[1]!=pic_size[1]):
        fp = BytesIO()
        image = Image.new('RGB', (pic_size[0],pic_size[1]-imgs_comb_size[1]), color = 'white')
        draw = ImageDraw.Draw(image)
        image.save(fp, 'PNG')
        imgs_comb=( np.vstack( (np.asarray(i) for i in [imgs_comb,PIL.Image.open(fp)] ) ))
        imgs_comb = PIL.Image.fromarray( imgs_comb)
    '''
    fp = BytesIO()
    imgs_comb.save( fp,'PNG' )

    return imgs_comb
Beispiel #15
0
    def depict(
        self,
        ids=None,
        sketch=True,
        filename=None,
        ipython=False,
        optimize=False,
        optimizemode="std",
        removeHs=True,
        legends=None,
        highlightAtoms=None,
        mols_perrow=3,
    ):
        """
        Depicts the molecules into a grid. It is possible to save it into an svg file and also generates a
        jupiter-notebook rendering

        Parameters
        ----------
        ids: list
            The index of the molecules to depict
        sketch: bool
            Set to True for 2D depiction
        filename: str
            Set the filename for the svg file
        ipython: bool
            Set to True to return the jupiter-notebook rendering
        optimize: bool
            Set to True to optimize the conformation. Works only with 3D.
        optimizemode: ['std', 'mmff']
            Set the optimization mode for 3D conformation
        removeHs: bool
            Set to True to hide hydrogens in the depiction
        legends: str
            The name to used for each molecule. Can be 'names':the name of themselves; or 'items': a incremental id
        highlightAtoms: list
            A List of atom to highligh for each molecule. It can be also a list of atom list, in this case different
            colors will be used
        mols_perrow: int
            The number of molecules to depict per row of the grid

        Returns
        -------
            ipython_svg: SVG object if ipython is set to True

        """
        from rdkit.Chem.AllChem import (
            Compute2DCoords,
            EmbedMolecule,
            MMFFOptimizeMolecule,
            ETKDG,
        )
        from rdkit.Chem import RemoveHs
        from moleculekit.smallmol.util import depictMultipleMols

        if sketch and optimize:
            raise ValueError(
                "Impossible to use optmization in  2D sketch representation")

        if legends is not None and legends not in ["names", "items"]:
            raise ValueError('The "legends" should be "names" or "items"')

        _smallmols = self.getMols(ids)

        if ids is None:
            _mols = [m._mol for m in self._mols]
        else:
            _mols = [m._mol for m in self.getMols(ids)]

        if highlightAtoms is not None:
            if len(highlightAtoms) != len(_mols):
                raise ValueError(
                    "The highlightAtoms {} should have the same length of the "
                    "mols {}".format(len(highlightAtoms), len(_mols)))

        if sketch:
            for _m in _mols:
                Compute2DCoords(_m)

        if removeHs:
            _mols = [RemoveHs(_m) for _m in _mols]

        # activate 3D coords optimization
        if optimize:
            if optimizemode == "std":
                for _m in _mols:
                    EmbedMolecule(_m)
            elif optimizemode == "mmff":
                for _m in _mols:
                    MMFFOptimizeMolecule(_m, ETKDG())

        legends_list = []
        if legends == "names":
            legends_list = [_m.getProp("ligname") for _m in _smallmols]
        elif legends == "items":
            legends_list = [str(n + 1) for n in range(len(_smallmols))]

        return depictMultipleMols(
            _mols,
            ipython=ipython,
            legends=legends_list,
            highlightAtoms=highlightAtoms,
            filename=filename,
            mols_perrow=mols_perrow,
        )
Beispiel #16
0
    def update_pertubation_image(self,
                                 mol_a_name,
                                 mol_b_name,
                                 core_smarts=None,
                                 save=False,
                                 verbosity=0,
                                 **kwargs):
        """ Generate mol images describing a pertubation between the ligand pair

        :param str mol_a_name: name of the molecule A
        :param str mol_b_name: name of the molecule B
        :param str core_smarts: use this smarts as common core
        :param bool save: automatically save data
        :param int verbosity: controls verbosity level
        """
        # verbosity = 5

        self.ligands_data[mol_a_name].setdefault('images', {})
        self.ligands_data[mol_a_name]['images'].setdefault('perturbations', {})
        self.ligands_data[mol_b_name].setdefault('images', {})
        self.ligands_data[mol_b_name]['images'].setdefault('perturbations', {})

        import rdkit.Chem
        this_mol_a = rdkit.Chem.Mol(self.ligands_data[mol_a_name]['molecule'])
        this_mol_b = rdkit.Chem.Mol(self.ligands_data[mol_b_name]['molecule'])

        if core_smarts is None:
            # Get core_smarts using find_mcs
            from merge_topologies import find_mcs
            this_mol_a.RemoveAllConformers()
            this_mol_b.RemoveAllConformers()
            core_smarts = find_mcs([this_mol_a, this_mol_b],
                                   savestate=self,
                                   verbosity=verbosity,
                                   **kwargs).smartsString

        try:
            # Test whether the correct data structure is already present
            assert len(self.ligands_data[mol_a_name]['images']['perturbations']
                       [mol_b_name][core_smarts]) > 0
            assert len(self.ligands_data[mol_b_name]['images']['perturbations']
                       [mol_a_name][core_smarts]) > 0
        except (KeyError, AssertionError):
            # It isn't, go on and create the images
            os_util.local_print(
                'Perturbation images for molecules {} and {} with common core "{}" were not found. '
                'Generating it.'.format(mol_a_name, mol_b_name, core_smarts),
                msg_verbosity=os_util.verbosity_level.debug,
                current_verbosity=verbosity)
        else:
            return None

        from rdkit.Chem.Draw import MolDraw2DSVG
        from rdkit.Chem.AllChem import Compute2DCoords, GenerateDepictionMatching2DStructure

        core_mol = rdkit.Chem.MolFromSmarts(core_smarts)
        Compute2DCoords(core_mol)

        for each_name, each_mol, other_mol in zip([mol_a_name, mol_b_name],
                                                  [this_mol_a, this_mol_b],
                                                  [mol_b_name, mol_a_name]):
            GenerateDepictionMatching2DStructure(each_mol,
                                                 core_mol,
                                                 acceptFailure=True)

            # Draw mol with hydrogens
            draw_2d_svg = MolDraw2DSVG(300, 150)
            draw_2d_svg.drawOptions().addStereoAnnotation = True
            not_common_atoms = [
                i.GetIdx() for i in each_mol.GetAtoms()
                if i.GetIdx() not in each_mol.GetSubstructMatch(core_mol)
            ]
            draw_2d_svg.DrawMolecule(each_mol,
                                     legend=each_name,
                                     highlightAtoms=not_common_atoms)
            draw_2d_svg.FinishDrawing()
            svg_data_hs = draw_2d_svg.GetDrawingText()

            # Draw mol without hydrogens
            draw_2d_svg = MolDraw2DSVG(300, 150)
            draw_2d_svg.drawOptions().addStereoAnnotation = True
            each_mol = rdkit.Chem.RemoveHs(each_mol)
            not_common_atoms = [
                i.GetIdx() for i in each_mol.GetAtoms()
                if i.GetIdx() not in each_mol.GetSubstructMatch(
                    rdkit.Chem.RemoveHs(core_mol))
            ]
            draw_2d_svg.DrawMolecule(each_mol,
                                     legend=each_name,
                                     highlightAtoms=not_common_atoms)
            draw_2d_svg.FinishDrawing()
            svg_data_nohs = draw_2d_svg.GetDrawingText()

            perturbation_imgs = self.ligands_data[each_name]['images'][
                'perturbations']
            perturbation_imgs.setdefault(other_mol, {})[core_smarts] = {
                '2d_hs': svg_data_hs,
                '2d_nohs': svg_data_nohs
            }

        if save:
            self.save_data()