annotate chemfp_clustering/butina_clustering.py @ 2:45f968b8bff6

Uploaded
author bgruening
date Tue, 26 Mar 2013 14:47:30 -0400
parents a8ac5250d59c
children a4e261ee0a51
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
1 #!/usr/bin/env python
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
2 """
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
3 Modified version of code examples from the chemfp project.
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
4 http://code.google.com/p/chem-fingerprints/
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
5 Thanks to Andrew Dalke of Andrew Dalke Scientific!
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
6 """
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
7
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
8 import chemfp
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
9 import sys
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
10 import os
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
11
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
12 chemfp_fingerprint_file = sys.argv[1]
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
13 tanimoto_threshold = float(sys.argv[2])
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
14 outfile = sys.argv[3]
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
15 processors = int(sys.argv[4])
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
16
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
17
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
18 def get_hit_indicies(hits):
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
19 return [id for (id, score) in hits]
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
20
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
21 out = open(outfile, 'w')
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
22 dataset = chemfp.load_fingerprints( chemfp_fingerprint_file )
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
23
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
24 chemfp.set_num_threads( processors )
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
25 search = dataset.threshold_tanimoto_search_arena(dataset, threshold = tanimoto_threshold)
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
26
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
27 # Reorder so the centroid with the most hits comes first.
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
28 # (That's why I do a reverse search.)
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
29 # Ignore the arbitrariness of breaking ties by fingerprint index
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
30 results = sorted( ( (len(hits), i, hits) for (i, hits) in enumerate(search.iter_indices_and_scores()) ),reverse=True)
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
31
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
32
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
33 # Determine the true/false singletons and the clusters
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
34 true_singletons = []
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
35 false_singletons = []
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
36 clusters = []
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
37
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
38 seen = set()
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
39
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
40 for (size, fp_idx, hits) in results:
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
41 if fp_idx in seen:
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
42 # Can't use a centroid which is already assigned
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
43 continue
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
44 seen.add(fp_idx)
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
45
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
46 if size == 1:
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
47 # The only fingerprint in the exclusion sphere is itself
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
48 true_singletons.append(fp_idx)
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
49 continue
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
50
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
51 members = get_hit_indicies(hits)
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
52 # Figure out which ones haven't yet been assigned
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
53 unassigned = [target_idx for target_idx in members if target_idx not in seen]
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
54
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
55 if not unassigned:
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
56 false_singletons.append(fp_idx)
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
57 continue
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
58
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
59 # this is a new cluster
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
60 clusters.append( (fp_idx, unassigned) )
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
61 seen.update(unassigned)
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
62
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
63 len_cluster = len(clusters)
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
64 #out.write( "#%s true singletons: %s\n" % ( len(true_singletons), " ".join(sorted(dataset.ids[idx] for idx in true_singletons)) ) )
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
65 #out.write( "#%s false singletons: %s\n" % ( len(false_singletons), " ".join(sorted(dataset.ids[idx] for idx in false_singletons)) ) )
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
66
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
67 out.write( "#%s true singletons\n" % len(true_singletons) )
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
68 out.write( "#%s false singletons\n" % len(false_singletons) )
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
69 out.write( "#clusters: %s\n" % len_cluster )
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
70
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
71
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
72 # Sort so the cluster with the most compounds comes first,
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
73 # then by alphabetically smallest id
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
74 def cluster_sort_key(cluster):
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
75 centroid_idx, members = cluster
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
76 return -len(members), dataset.ids[centroid_idx]
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
77
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
78 clusters.sort(key=cluster_sort_key)
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
79
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
80
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
81 for centroid_idx, members in clusters:
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
82 centroid_name = dataset.ids[centroid_idx]
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
83 out.write("%s\t%s\t%s\n" % (centroid_name, len(members), " ".join(dataset.ids[idx] for idx in members)))
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
84 #ToDo: len(members) need to be some biggest top 90% or something ...
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
85
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
86 for idx in true_singletons:
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
87 out.write("%s\t%s\n" % (dataset.ids[idx], 0))
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
88
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
89 out.close()
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
90
a8ac5250d59c Uploaded
bgruening
parents:
diff changeset
91