AF3 rescore with gnina

Setup

Split the AF3 output .cif into protein.pdb and ligand.sdf


source

ChainSelect

 ChainSelect (chain_ids)

Select chain to save


source

rename_residues

 rename_residues (structure, chain_id, new_resname='LIG')

Rename residue name from LIG_L to LIG as LIG_L exceeds lengths and leads to error in RDKit


source

split_cif

 split_cif (cif_path, rec_chain_id, lig_chain_id, rec_pdb_path,
            lig_pdb_path)

Split AF3 output CIF to protein and ligand PDBs


source

pdb2sdf

 pdb2sdf (pdb_path, sdf_path)

Convert ligand pdb to sdf file


source

prepare_rec_lig

 prepare_rec_lig (cif_path, rec_chain_id, lig_chain_id, rec_pdb_path,
                  lig_pdb_path)

Split AF3 cif to protein.pdb (chainA) and ligand.sdf (chainL)

# AF3 output
prepare_rec_lig('gnina_test/cif/test.cif','A','L','gnina_test/chain_A.pdb','gnina_test/chain_L.sdf')
# Protenix output
prepare_rec_lig('gnina_test/protenix_cif/test.cif','A','B','gnina_test/protenix_A.pdb','gnina_test/protenix_B.sdf')

gnina score

According to gnina doc:

gnina -r chain_A.pdb -l chain_L.sdf --minimize -o minimized.sdf.gz

source

gnina_rescore_local

 gnina_rescore_local (protein_pdb, ligand_sdf, CNN_affinity=True,
                      vinardo=False)
Type Default Details
protein_pdb receptor file
ligand_sdf ligand file
CNN_affinity bool True
vinardo bool False if True, use vinardo instead of vina
# %%time
# out = gnina_rescore_local('gnina_test/chain_A.pdb',
#                           'gnina_test/chain_L.sdf',
#                           CNN_affinity=False
#                           )
# out

source

gnina_rescore_docker

 gnina_rescore_docker (protein_pdb, ligand_sdf, CNN_affinity=True,
                       vinardo=False)

Run GNINA rescoring using Docker. Supports receptor and ligand in different folders.

# %%time
# out = gnina_rescore_docker('gnina_test/chain_A.pdb',
#                            'gnina_test/chain_L.sdf',
#                            CNN_affinity=False)
# out

source

extract_gnina_rescore

 extract_gnina_rescore (txt)

Extract GNINA output metrics into a dictionary (partial match allowed).

out = "              _             \n             (_)            \n   __ _ _ __  _ _ __   __ _ \n  / _` | '_ \\| | '_ \\ / _` |\n | (_| | | | | | | | | (_| |\n  \\__, |_| |_|_|_| |_|\\__,_|\n   __/ |                    \n  |___/                     \n\ngnina  master:e9cb230+   Built Feb 11 2023.\ngnina is based on smina and AutoDock Vina.\nPlease cite appropriately.\n\nWARNING: No GPU detected. CNN scoring will be slow.\nRecommend running with single model (--cnn crossdock_default2018)\nor without cnn scoring (--cnn_scoring=none).\n\nCommandline: ./gnina -r chain_A.pdb -l chain_L.sdf --minimize\nAffinity: -10.96345  -1.51405 (kcal/mol)\nRMSD: 1.15404\nCNNscore: 0.49978 \nCNNaffinity: 7.32008\nCNNvariance: 0.18500\n"
extract_gnina_rescore(out)
{'binding_energy': -10.96345,
 'uncertainty': -1.51405,
 'RMSD': 1.15404,
 'CNNscore': 0.49978,
 'CNNaffinity': 7.32008,
 'CNNvariance': 0.185}
# set CNN affinity to False
out2 = "              _             \n             (_)            \n   __ _ _ __  _ _ __   __ _ \n  / _` | '_ \\| | '_ \\ / _` |\n | (_| | | | | | | | | (_| |\n  \\__, |_| |_|_|_| |_|\\__,_|\n   __/ |                    \n  |___/                     \n\ngnina v1.1 master:e4cb380+   Built Dec 18 2023.\ngnina is based on smina and AutoDock Vina.\nPlease cite appropriately.\n\nWARNING: No GPU detected. CNN scoring will be slow.\nRecommend running with single model (--cnn crossdock_default2018)\nor without cnn scoring (--cnn_scoring=none).\n\nCommandline: ./gnina -r gnina_test/chain_A.pdb -l gnina_test/chain_L.sdf --minimize --cnn_scoring none\nAffinity: -10.96345  -1.51405 (kcal/mol)\nRMSD: 1.15404\nCNNscore: -1.00000 \nCNNaffinity: 0.00000\n"
extract_gnina_rescore(out2)
{'binding_energy': -10.96345,
 'uncertainty': -1.51405,
 'RMSD': 1.15404,
 'CNNscore': -1.0,
 'CNNaffinity': 0.0}

source

get_gnina_rescore

 get_gnina_rescore (cif_path, rec_chain_id='A', lig_chain_id='L',
                    CNN_affinity=True, vinardo=False, is_local=True)

Split the CIF into receptor and ligand folders, then extract the GNINA rescored affinity score

# get_gnina_rescore('gnina_test/cif/test.cif',
#                   rec_chain_id='A', 
#                   lig_chain_id='L',
#                   CNN_affinity=False,
#                   is_local=True)
# get_gnina_rescore('gnina_test/cif/test.cif',
#                   rec_chain_id='A', 
#                   lig_chain_id='L',
#                   CNN_affinity=False,
#                   vinardo=True,
#                   is_local=True)

Non-parallel for multiple .cif files:

# cifs = L(Path('gnina_test/cif').expanduser().glob("*.cif")) # just take cif file

# out = {p.stem: get_gnina_rescore(p) for p in tqdm(cifs)}

# out_df = pd.DataFrame(out).T

source

get_gnina_rescore_folder

 get_gnina_rescore_folder (cif_folder, rec_chain_id='A', lig_chain_id='L',
                           CNN_affinity=True, vinardo=False,
                           is_local=True)

Parallel processing to get gnina rescore given folder path

Vinardo scoring:

# %%time
# get_gnina_rescore_folder('gnina_test/cif',
#                          rec_chain_id='A', 
#                          lig_chain_id='L',
#                          CNN_affinity=False,
#                          vinardo=True,
#                          )

Vina scoring:

# get_gnina_rescore_folder('gnina_test/cif',
#                          rec_chain_id='A', 
#                          lig_chain_id='L',
#                          CNN_affinity=False,
#                          vinardo=False,
#                          )

End