<jupyter_start><jupyter_text>Docking Oracle and Generative Leaderboard Demo <NAME> (<EMAIL>)  Docking Oracle<jupyter_code># <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., <NAME>., ... & <NAME>. (2021). A practical guide to large-scale docking. Nature Protocols, 1-34.<jupyter_output><empty_output><jupyter_text>We use AutoDock Vina as backend via PyScreener, please install PyScreener following https://github.com/coleygroup/pyscreener We provide 9 curated targets: PDB ID: 3pbl, 1iep, 2rgp, 3eml, 3ny8, 4rlu, 4unn, 5mo4, 7l11. Using them is similar to using other oracles:<jupyter_code>from tdc import Oracle
import time

oracle = Oracle(name='3pbl_docking')
t1 = time.time()
print(f"Docking score: {oracle('CCNC(=O)c1ccc(NC(=O)N2CC[C@H](C)[C@H](O)C2)c(C)c1')} kcal/mol")
print(f"Consumed time: {time.time() - t1:.3f} s")
oracle = Oracle(name='7l11_docking')
t1 = time.time()
print(f"Docking score: {oracle('CCNC(=O)c1ccc(NC(=O)N2CC[C@H](C)[C@H](O)C2)c(C)c1')} kcal/mol")
print(f"Consumed time: {time.time() - t1:.3f} s")
t1 = time.time()
print(f"Docking score: {oracle(['CCNC(=O)c1ccc(NC(=O)N2CC[C@H](C)[C@H](O)C2)c(C)c1', 'CCNC(=O)c1ccc(NC(=O)N2CC[C@H](C)[C@H](O)C2)c(C)c1'])} kcal/mol")
print(f"Consumed time: {time.time() - t1:.3f} s")<jupyter_output>Docking: 100%|██████████| 1/1 [00:23<00:00, 23.86s/ligand]
Docking: 100%|██████████| 1/1 [00:24<00:00, 24.44s/ligand]<jupyter_text>We also have a backend of AutoDock Vina, please install vina following https://autodock-vina.readthedocs.io/en/latest/installation.htmlpython-bindings<jupyter_code># oracle_vina = Oracle(name='3pbl_docking_vina')
# t1 = time.time()
# print(f"Docking score: {oracle_vina('CCNC(=O)c1ccc(NC(=O)N2CC[C@H](C)[C@H](O)C2)c(C)c1', output_file='out.pdbqt', n_poses=1)} kcal/mol")
# print(f"Consumed time: {time.time() - t1:.3f} s")<jupyter_output><empty_output><jupyter_text>Visualize the result<jupyter_code>import py3Dmol
import os

pdbid = '3pbl'

# conda install openbabel -c conda-forge
os.system("obabel -i pdbqt out.pdbqt -o pdb -O " + pdbid + "_ligand.pdb")
os.system("obabel -i pdbqt oracle/" + pdbid + ".pdbqt -o pdb -O" + pdbid + "_receptor.pdb")
os.system("obabel -i pdbqt out.pdbqt -o xyz -O " + pdbid + "_ligand.xyz")
lines = []
for line in open(pdbid + "_ligand.xyz", 'rt'): 
    lines.append(line.strip())
lines = lines[2:]

xs = [float(line.split()[1]) for line in lines]
ys = [float(line.split()[2]) for line in lines]
zs = [float(line.split()[3]) for line in lines]
center_x = sum(xs)/len(lines)
center_y = sum(ys)/len(lines)
center_z = sum(zs)/len(lines)
print(center_x, center_y, center_z)

def visbox2(objeto, center, box_size):  
    objeto.addBox({'center':{'x': center[0],'y': center[1],'z': center[2]}, 
                   'dimensions': {'w': box_size[0],'h': box_size[1],'d': box_size[2]},'color':'blue','opacity': 0.5})

def complxvis(objeto,protein_name,ligand_name):
    mol1 = open(protein_name, 'r').read()
    mol2 = open(ligand_name, 'r').read()
    objeto.addModel(mol1,'pdb')
    objeto.setStyle({'cartoon': {'color':'spectrum'}})
    objeto.addModel(mol2,'pdb')
    objeto.setStyle({'model':1},{'stick':{}})

def vismol(center=[center_x, center_y, center_z], box_size=[20, 20, 20]):  
    mol_view = py3Dmol.view(1200, 800)  
    visbox2(mol_view, center, box_size)
    complxvis(mol_view, pdbid + '_receptor.pdb', pdbid + '_ligand.pdb')
    mol_view.setBackgroundColor('white')
    mol_view.rotate(90, {'x':0,'y':1,'z':0},viewer=(0,1));
    mol_view.zoomTo()  
    mol_view.show()

vismol()<jupyter_output>7.394807692307693 22.16196153846154 23.601230769230767<jupyter_text>Besides, we also provide flexibility for users to dock against any protein targets:<jupyter_code># oracle = Oracle(name='docking_score', receptor_pdbqt_file=, center=, box_size=)
# oracle('c1ccccc1', output_file='out.pdbqt', n_poses=1)<jupyter_output><empty_output><jupyter_text>Generative Modeling Leaderboard TODO Intro to generative modeling and leaderboard<jupyter_code>from tdc import utils
utils.retrieve_benchmark_names('Docking_Group')
from tdc.benchmark_group import docking_group
group = docking_group(path='./data', num_cpus=4, num_max_call=5000)

benchmark = group.get('3pbl', num_max_call = 5000) 
predictions = {}
oracle_fct, data, name = benchmark['oracle'], benchmark['data'], benchmark['name'] 
data.head()
oracle_fct(data.smiles[0])
name<jupyter_output><empty_output><jupyter_text>A genetic algorithm with SynNet<jupyter_code># <NAME>., <NAME>., & <NAME>. (2021). Amortized Tree Generation for Bottom-up Synthesis Planning and Synthesizable Molecular Design. arXiv preprint arXiv:2110.06389.<jupyter_output><empty_output><jupyter_text><jupyter_code>import json

with open('opt_drd3_5000.json', 'r') as f:
    pred_smiles = json.load(f)
pred_smiles
predictions[name] = pred_smiles 

out = group.evaluate(predictions)
out['3pbl']['5000'].keys()
out['3pbl']['5000']
# predictions[name] = pred_smiles 
'''
pred_smiles format is a dictionary of the top 100 generated SMILES: 
{5000: {
  'C=C=C=C(C#CON(N=O)C(=NO)C(O)=NC#CC)C(N=CC)(ON=NO)C(=CNN=NNCC)OO': -6.0,
  'CNN=CC(CC(O)(CCN(O)O)NC(=N)C(C)=COO)OC(=O)N=NON=C(O)CC=CNO': -7.2,
  ...
  '(O)OC#CNOC(N)C(=O)NOC(CN)C1=C=C=C=C1': -9.8
 },
 ### if you also evaluate on 1000/500/100 maximum calls
 1000: {
  .....
 }
}

Note: if no docking score is generated by the model for the final 
100 SMILES, you can also input a list of 100 generated SMILES and 
TDC will call the docking scores in the evaluate function.
'''

# out = group.evaluate(predictions, m1_api = 'XXXXX')
'''
{'DRD3': {5000: {'top100': -10.2,
          'top10': -11.3,
          'top1': -12.3,
          'diversity': 0.6,
          'novelty': 0.7,
          '%pass': 0.7,
          'top1_%pass': -11.2,
          'm1': 2.5,
          'top smiles': ['XXX', 'XXX', ...]
          },
        1000: {....
          }
        }          
}

Note that if you put save_dict = True in evaluate function, it 
would return more detailed evaluation outcomes, namely the list of 
smiles pass the filter, a dictionary of smiles with m1 scores and docking scores.

We ask users to submit at least three random runs of models for robustness. 
You can use following functions to obtain submission ready format:
'''
# predictions_runs = [pred_run1, pred_run2, pred_run3]
# out = group.evaluate_many(predictions_runs, save_file_name = 'result', m1_api = 'XXXXX')
'''
{'DRD3': {5000: {'top100': [-10.2, 0.12],
          'top10': [-11.3, 0.01],
          'top1': [-12.3, 0.02],
          'diversity': [0.6, 0.001],
          'novelty': [0.7, 0.01],
          '%pass': [0.7, 0.02],
          'top1_%pass': [-11.2, 0.03],
          'm1': [5.5, 0.04],
          'top smiles': ['XXX', 'XXX', ...] # superset of runs
          },
        1000: {....
          }
        }          
}

In default, this evaluate_many function will call group.evaluate for each run. If you have the evaluate result for each fold, simply specify it with 'results_individual = XX' to skip the evaluation calls.
'''<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1811180832857958, 'fraction_numerical': 0.05219623502567028, 'mean_word_length': 4.530757097791798, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 43, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '576267', 'license': 'MIT', 'n_tokens_mistral': 3077, 'n_tokens_neox': 2795, 'n_words': 592, 'path': 'tutorials/User_Group/UserGroupMeeting_Wenhao.ipynb', 'repo_name': 'benb111/TDC', 'size': '7063'}