<jupyter_start><jupyter_text>`modtox.Collection`A collection is a group of `modtox.Molecules` that has some functionalities. First of all, let's load the collection from sdf files.<jupyter_code>from modtox.modtox.Molecules.col import CollectionFromSDF
import os
target = "5tnt"
ACTIVES = os.path.join(os.path.abspath(""), "data", target, "actives.sdf")
INACTIVES = os.path.join(os.path.abspath(""), "data", target, "inactives.sdf")

from rdkit import RDLogger
RDLogger.DisableLog('rdApp.*')  # Disable warnings (molecule is tagged as 3D, but all Z coords are zero)

c = CollectionFromSDF(ACTIVES, INACTIVES)<jupyter_output><empty_output><jupyter_text>Calculating featuresThe following features can be calculated for each molecule:- __Topological__ fingerprints from `rdkit` module.- __Morgan__ fingerprints from `rdkit` module. - __Mordred__ descriptors from `mordred` module.In addition we can add the previously calculated docking features (__Glide features__), which we will need to supply the path to the `.csv`.  We will calculate the mordred descriptors and the topological fingerprints for this collection:<jupyter_code>from modtox.modtox.utils.enums import Features
c.add_features(Features.mordred, Features.topo, Features.morgan)<jupyter_output>Calculating mordred descriptors...<jupyter_text>The features are stored within each molecule of the collection. Let's illustrate that:<jupyter_code>mol = c.molecules[0]
mol.features.keys()
%pprint
mol.features[Features.mordred]
print(f"Number of mordred descriptors: {len(mol.features[Features.mordred])}")
print(f"Number of topological fingerprints: {len(mol.features[Features.topo])}")<jupyter_output>Number of mordred descriptors: 1613
Number of topological fingerprints: 2048<jupyter_text>ClusteringTanimoto clustering can be performed to the collection. The clustering can be done using topological or Morgan fingerprints (which will be calculated if are not already calculated). A distance cut off value needs to be supplied. The higher the cut off, the smaller the number of clusters (more members per cluster).    Clustering sets the attribute `c.clusters`: list of clusters with the indexes of the molecules. The first item of each cluster is the cluster centroid.  Clustering also links a `modtox.Cluster` object to each molecule.<jupyter_code>c.clusters = c.cluster(cutoff=0.4, fp="topological")
first_cluster = c.clusters[0]
first_cluster<jupyter_output><empty_output><jupyter_text>> *Note:* numbers correspond to the indexes of `c.molecules` list.  For the first cluster<jupyter_code>i = 0
print(f"Cluster ID: {i}")
print(f"Cluster members: {len(c.clusters[i])}")
print(f"Cluster centroid: {c.clusters[i][0]}")<jupyter_output>Cluster ID: 0
Cluster members: 282
Cluster centroid: 144<jupyter_text>And if we access molecule with index 67:<jupyter_code>mol = c.molecules[c.clusters[0][0]]
print(f"Cluster ID: {mol.cluster.id}")
print(f"Cluster members: {mol.cluster.members}")
print(f"Cluster centroid: {mol.cluster.is_centroid}")<jupyter_output>Cluster ID: 0
Cluster members: 282
Cluster centroid: True<jupyter_text>Clustering will be used for removing outliers of the collection. To help us decide the clustering strategy, we can quickly plot different cutoff values and fingerprints type.  For visualization purposes, a list of outlier threshold (e.g.: the threshold of members a cluster needs to have to not be considered outlier) can be supplied.<jupyter_code>m_plot = c.plot_clustering_parameters(cutoffs=[0.2, 0.3, 0.4, 0.5, 0.6], thresholds=[1, 5, 10, 25, 50], fp="morgan")
t_plot = c.plot_clustering_parameters(cutoffs=[0.2, 0.3, 0.4, 0.5, 0.6], thresholds=[1, 5, 10, 25, 50], fp="topological")<jupyter_output><empty_output><jupyter_text>For this example, the cutoff value selected is 0.4 for Morgan fingerprints. It is important to cluster the collection again or it will be clustered according to the last parameters.<jupyter_code>cutoff = 0.3
fp = "morgan"
c.cluster(cutoff=cutoff, fp=fp)
with open(f"data/{target}/cluster.txt", "w") as f:
    f.write(f"cutoff = {cutoff}\nfp={fp}")
;<jupyter_output><empty_output><jupyter_text>Export to dataframeFinally, collection can be exported to a `pandas` dataframe for the next steps. The dataframe will include all calculated features and cluster information.<jupyter_code>df = c.to_dataframe()
import pandas as pd
pd.set_option('display.max_rows', 10)
pd.set_option('display.max_columns', 10)
pd.set_option('display.width', 1000)
pd.set_option('display.colheader_justify', 'center')
pd.set_option('display.precision', 3)

df
import pickle5
with open(f"data/{target}/{target}.pickle", "wb") as f:
    pickle5.dump(c, f)
    
df.to_csv(f"data/{target}/mordred_topo_morgan.csv")
m_plot.savefig(f"data/{target}/morgan_clusters.png")
t_plot.savefig(f"data/{target}/topo_clusters.png")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11037481880306482, 'fraction_numerical': 0.016980741354317663, 'mean_word_length': 6.511664074650078, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 34, 'https://': 0, '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': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '315848', 'license': 'Apache-2.0', 'n_tokens_mistral': 1666, 'n_tokens_neox': 1532, 'n_words': 474, 'path': 'examples/collection.ipynb', 'repo_name': 'danielSoler93/modtox', 'size': '4829'}