MASSA-Algorithm 2.2.0__py3-none-any.whl → 2.2.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- MASSA_Algorithm/MASSAextraction.py +11 -4
- MASSA_Algorithm/MASSAlogos.py +1 -1
- MASSA_Algorithm/MASSAopen_files.py +26 -0
- MASSA_Algorithm/pyMASSA.py +353 -353
- {massa_algorithm-2.2.0.dist-info → massa_algorithm-2.2.2.dist-info}/METADATA +183 -180
- {massa_algorithm-2.2.0.dist-info → massa_algorithm-2.2.2.dist-info}/RECORD +10 -10
- {massa_algorithm-2.2.0.dist-info → massa_algorithm-2.2.2.dist-info}/WHEEL +1 -1
- {massa_algorithm-2.2.0.dist-info → massa_algorithm-2.2.2.dist-info}/licenses/LICENSE +661 -661
- {massa_algorithm-2.2.0.dist-info → massa_algorithm-2.2.2.dist-info}/entry_points.txt +0 -0
- {massa_algorithm-2.2.0.dist-info → massa_algorithm-2.2.2.dist-info}/top_level.txt +0 -0
MASSA_Algorithm/pyMASSA.py
CHANGED
|
@@ -1,353 +1,353 @@
|
|
|
1
|
-
from MASSA_Algorithm import MASSAlogos
|
|
2
|
-
from MASSA_Algorithm import MASSAargs
|
|
3
|
-
from MASSA_Algorithm import MASSAod
|
|
4
|
-
from MASSA_Algorithm import MASSAopen_files
|
|
5
|
-
from MASSA_Algorithm import MASSAextraction
|
|
6
|
-
from MASSA_Algorithm import MASSAdescriptors
|
|
7
|
-
from MASSA_Algorithm import MASSApreparation
|
|
8
|
-
from MASSA_Algorithm import MASSAcluster
|
|
9
|
-
from MASSA_Algorithm import MASSAsplit
|
|
10
|
-
from MASSA_Algorithm import MASSAmoloutput
|
|
11
|
-
import time
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def returns_zero(total, test, validation):
|
|
15
|
-
"""
|
|
16
|
-
Description:
|
|
17
|
-
It evaluates whether the distribution is inadequate. That is,
|
|
18
|
-
when the iterated cluster has a percentage greater than 0.5%
|
|
19
|
-
in the complete dataset but less than 0.5% in the test set.
|
|
20
|
-
|
|
21
|
-
Args:
|
|
22
|
-
total (dict):
|
|
23
|
-
Percentage of molecules in each cluster for the whole dataset.
|
|
24
|
-
|
|
25
|
-
test (dict):
|
|
26
|
-
Percentage of molecules in each cluster for the test subset.
|
|
27
|
-
|
|
28
|
-
validation (dict):
|
|
29
|
-
Percentage of molecules in each cluster for the validation subset.
|
|
30
|
-
|
|
31
|
-
Returns:
|
|
32
|
-
definer (boolean): Returns True if the distribution is
|
|
33
|
-
inadequate, and False if it is adequate.
|
|
34
|
-
"""
|
|
35
|
-
definer = False
|
|
36
|
-
for i in total.keys():
|
|
37
|
-
if (total[i] > 0.5) and (test[i] <= 0.5):
|
|
38
|
-
# Definer = True (Distribution was not done properly).
|
|
39
|
-
definer = True
|
|
40
|
-
elif validation != None:
|
|
41
|
-
if (total[i] > 0.5) and (validation[i] <= 0.5):
|
|
42
|
-
definer = True
|
|
43
|
-
return definer
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def py_massa(
|
|
47
|
-
file_input=str(),
|
|
48
|
-
working_directory=str(),
|
|
49
|
-
job_name="MASSAoutput.sdf",
|
|
50
|
-
extension_type="svg",
|
|
51
|
-
dendrogram_xfont_size=5,
|
|
52
|
-
barplot_xfont_size=9,
|
|
53
|
-
training_percent=round(float(0.8), 3),
|
|
54
|
-
bioactivities_as_args=None,
|
|
55
|
-
npcs=0.85,
|
|
56
|
-
svd_parameter="full",
|
|
57
|
-
linkage_method="complete",
|
|
58
|
-
flag_dendrogram=True,
|
|
59
|
-
splitting_strategy="tt",
|
|
60
|
-
drop_errors=True,
|
|
61
|
-
large_library="auto"
|
|
62
|
-
):
|
|
63
|
-
# Initializing from Python.
|
|
64
|
-
# Print the program logo:
|
|
65
|
-
MASSAlogos.python_logo()
|
|
66
|
-
start_time = time.time()
|
|
67
|
-
|
|
68
|
-
# Defining the working_directory alias:
|
|
69
|
-
working_directory = f"{working_directory}/"
|
|
70
|
-
directoryfile_output = working_directory
|
|
71
|
-
|
|
72
|
-
# It creates the output directories:
|
|
73
|
-
MASSAod.output_directory(directoryfile_output, flag_dendrogram)
|
|
74
|
-
|
|
75
|
-
# Test nPCs:
|
|
76
|
-
if npcs > 1:
|
|
77
|
-
npcs = int(npcs)
|
|
78
|
-
elif (npcs > 0) and (npcs <= 1):
|
|
79
|
-
npcs = float(npcs)
|
|
80
|
-
else:
|
|
81
|
-
raise ValueError(
|
|
82
|
-
f"ERROR: The defined number of main components is invalid. npcs = {str(npcs)}")
|
|
83
|
-
|
|
84
|
-
# Autodetect if the biological activities are set.
|
|
85
|
-
if isinstance(bioactivities_as_args, str):
|
|
86
|
-
number_bioact = 1
|
|
87
|
-
bioactivities_as_args = [bioactivities_as_args]
|
|
88
|
-
elif isinstance(bioactivities_as_args, list):
|
|
89
|
-
number_bioact = len(bioactivities_as_args)
|
|
90
|
-
elif bioactivities_as_args == None:
|
|
91
|
-
raise ValueError(
|
|
92
|
-
"The biological activities are not specified. bioactivities_as_args == None")
|
|
93
|
-
|
|
94
|
-
# Create log.txt file in directory:
|
|
95
|
-
log_path = directoryfile_output+'log.txt'
|
|
96
|
-
write_log = open(log_path, 'w')
|
|
97
|
-
|
|
98
|
-
if isinstance(file_input, str):
|
|
99
|
-
# Initial file management:
|
|
100
|
-
# Read molecules.
|
|
101
|
-
mols = MASSAopen_files.read_molecules(
|
|
102
|
-
file_input, write_log, drop_errors)
|
|
103
|
-
else:
|
|
104
|
-
mols = file_input
|
|
105
|
-
|
|
106
|
-
# Test if large_library is set:
|
|
107
|
-
if isinstance(large_library, str):
|
|
108
|
-
if large_library.lower() == 'true':
|
|
109
|
-
large_library = True
|
|
110
|
-
elif large_library.lower() == 'false':
|
|
111
|
-
large_library = False
|
|
112
|
-
elif large_library.lower() == 'auto':
|
|
113
|
-
if int(len(mols)) > 9999:
|
|
114
|
-
large_library = True
|
|
115
|
-
else:
|
|
116
|
-
large_library = False
|
|
117
|
-
|
|
118
|
-
# If auto detection is enable to select the initial cluster algorithm.
|
|
119
|
-
if large_library == 'auto':
|
|
120
|
-
if int(len(mols)) > 9999:
|
|
121
|
-
large_library = True
|
|
122
|
-
else:
|
|
123
|
-
large_library = False
|
|
124
|
-
|
|
125
|
-
if large_library == True:
|
|
126
|
-
# Deactivates the HCA dendrogram.
|
|
127
|
-
flag_dendrogram = False
|
|
128
|
-
|
|
129
|
-
# Extracting the property names from the ".sdf" input file.
|
|
130
|
-
sdf_property_names = MASSAopen_files.get_sdf_property_names(mols)
|
|
131
|
-
# Structure 3D management - It adds hydrogens keeping 3D coordenates.
|
|
132
|
-
mols_h = MASSAopen_files.hydrogen_add(mols)
|
|
133
|
-
|
|
134
|
-
# Extraction properties from ".sdf":
|
|
135
|
-
# It extracts the names of the molecules and creates a name:molecule dictionary and a dataframe.
|
|
136
|
-
names, dataframe = MASSAextraction.name_extraction(mols_h)
|
|
137
|
-
|
|
138
|
-
# It defines a list of what biological activities are being extracted.
|
|
139
|
-
biological_activity = MASSAextraction.the_biological_handler(
|
|
140
|
-
sdf_property_names, number_bioact, bioactivities_as_args)
|
|
141
|
-
# It adds the biological activities to the dataframe.
|
|
142
|
-
dataframe = MASSAextraction.list_activities(dataframe, biological_activity)
|
|
143
|
-
|
|
144
|
-
# Get fingeprint and other descriptors:
|
|
145
|
-
# Get physicochemical descriptors.
|
|
146
|
-
dataframe = MASSAdescriptors.physicochemical_descriptors(dataframe)
|
|
147
|
-
# Get AtomPairs fingerprint.
|
|
148
|
-
dataframe = MASSAdescriptors.atompairs_fingerprint(dataframe)
|
|
149
|
-
|
|
150
|
-
# Normalizes physicochemical and biological properties.
|
|
151
|
-
# Creates matrices for the three domains (struc, phys-chem, bio):
|
|
152
|
-
bio_matrix, phch_matrix, fp_matrix = MASSApreparation.normalizer_or_matrix(
|
|
153
|
-
dataframe, biological_activity)
|
|
154
|
-
|
|
155
|
-
# PCA:
|
|
156
|
-
# PCA for the biological domain.
|
|
157
|
-
bio_pca = MASSApreparation.pca_maker(bio_matrix, npcs, svd_parameter)
|
|
158
|
-
# PCA for the physicochemical domain.
|
|
159
|
-
phch_pca = MASSApreparation.pca_maker(phch_matrix, npcs, svd_parameter)
|
|
160
|
-
# PCA for the structural domain.
|
|
161
|
-
fp_pca = MASSApreparation.pca_maker(fp_matrix, npcs, svd_parameter)
|
|
162
|
-
|
|
163
|
-
if large_library == True:
|
|
164
|
-
# First clustering (MiniBatch-KMeans):
|
|
165
|
-
# It performs KMeans clustering for the biological domain.
|
|
166
|
-
bio_hca = MASSAcluster.kmeans_clusters(
|
|
167
|
-
bio_pca, names, 'bio', directoryfile_output, extension_type)
|
|
168
|
-
# It performs KMeans clustering for the physicochemical domain.
|
|
169
|
-
phch_hca = MASSAcluster.kmeans_clusters(
|
|
170
|
-
phch_pca, names, 'PhCh', directoryfile_output, extension_type)
|
|
171
|
-
# It performs KMeans clustering for the structural domain.
|
|
172
|
-
fp_hca = MASSAcluster.kmeans_clusters(
|
|
173
|
-
fp_pca, names, 'FP', directoryfile_output, extension_type)
|
|
174
|
-
else:
|
|
175
|
-
# First clustering (HCA):
|
|
176
|
-
# It performs HCA clustering without generating the dendrogram for the biological domain.
|
|
177
|
-
leaves_cluster_bio, bio_hca, linkage_bio, cutoff_bio = MASSAcluster.hca_clusters(
|
|
178
|
-
bio_pca, names, 'bio', directoryfile_output, extension_type, linkage_method)
|
|
179
|
-
# It performs HCA clustering without generating the dendrogram for the physicochemical domain.
|
|
180
|
-
leaves_cluster_phch, phch_hca, linkage_phch, cutoff_phch = MASSAcluster.hca_clusters(
|
|
181
|
-
phch_pca, names, 'PhCh', directoryfile_output, extension_type, linkage_method)
|
|
182
|
-
# It performs HCA clustering without generating the dendrogram for the structural domain.
|
|
183
|
-
leaves_cluster_fp, fp_hca, linkage_fp, cutoff_fp = MASSAcluster.hca_clusters(
|
|
184
|
-
fp_pca, names, 'FP', directoryfile_output, extension_type, linkage_method)
|
|
185
|
-
|
|
186
|
-
# It adds the biological cluster identification to the spreadsheet.
|
|
187
|
-
dataframe = MASSApreparation.organize_df_clusterization(
|
|
188
|
-
dataframe, bio_hca, 'bio')
|
|
189
|
-
# It adds the physicochemical cluster identification to the spreadsheet.
|
|
190
|
-
dataframe = MASSApreparation.organize_df_clusterization(
|
|
191
|
-
dataframe, phch_hca, 'PhCh')
|
|
192
|
-
# It adds the structural cluster identification to the spreadsheet.
|
|
193
|
-
dataframe = MASSApreparation.organize_df_clusterization(
|
|
194
|
-
dataframe, fp_hca, 'FP')
|
|
195
|
-
|
|
196
|
-
# Second clustering (Kmodes):
|
|
197
|
-
# It creates a matrix with cluster identifications for each of the three domains for Kmodes.
|
|
198
|
-
matrix_for_kmodes = MASSApreparation.organize_for_kmodes(dataframe)
|
|
199
|
-
# It performs Kmodes clustering for the general domain.
|
|
200
|
-
all_hca = MASSAcluster.kmodes_clusters(matrix_for_kmodes, names,
|
|
201
|
-
directoryfile_output, extension_type)
|
|
202
|
-
# It adds the general cluster identification to the spreadsheet.
|
|
203
|
-
dataframe = MASSApreparation.organize_df_clusterization(
|
|
204
|
-
dataframe, all_hca, 'all')
|
|
205
|
-
|
|
206
|
-
# Split into training, test:
|
|
207
|
-
dataframe, test_or_val_molecules = MASSAsplit.split_train_test_sets(
|
|
208
|
-
dataframe, training_percent, splitting_strategy)
|
|
209
|
-
|
|
210
|
-
# Bar plot of frequencies
|
|
211
|
-
# (Calculates the percentages of molecules in each cluster for each
|
|
212
|
-
# dataset and generates a bar graph for each domain):
|
|
213
|
-
|
|
214
|
-
# Biological Bar Plot
|
|
215
|
-
bio_total, bio_training, bio_test, bio_val = MASSAsplit.freq_clusters(
|
|
216
|
-
dataframe,
|
|
217
|
-
directoryfile_output,
|
|
218
|
-
extension_type,
|
|
219
|
-
'Cluster_Biological',
|
|
220
|
-
barplot_xfont_size,
|
|
221
|
-
splitting_strategy)
|
|
222
|
-
# Physicochemical Bar Plot
|
|
223
|
-
phch_total, phch_training, phch_test, phch_val = MASSAsplit.freq_clusters(
|
|
224
|
-
dataframe,
|
|
225
|
-
directoryfile_output,
|
|
226
|
-
extension_type,
|
|
227
|
-
'Cluster_Physicochemical',
|
|
228
|
-
barplot_xfont_size,
|
|
229
|
-
splitting_strategy)
|
|
230
|
-
# Structural Bar Plot
|
|
231
|
-
fp_total, fp_training, fp_test, fp_val = MASSAsplit.freq_clusters(
|
|
232
|
-
dataframe,
|
|
233
|
-
directoryfile_output,
|
|
234
|
-
extension_type,
|
|
235
|
-
'Cluster_Structural',
|
|
236
|
-
barplot_xfont_size,
|
|
237
|
-
splitting_strategy)
|
|
238
|
-
# General Bar Plot
|
|
239
|
-
all_total, all_training, all_test, all_val = MASSAsplit.freq_clusters(
|
|
240
|
-
dataframe,
|
|
241
|
-
directoryfile_output,
|
|
242
|
-
extension_type,
|
|
243
|
-
'Cluster_General',
|
|
244
|
-
barplot_xfont_size,
|
|
245
|
-
splitting_strategy)
|
|
246
|
-
|
|
247
|
-
# Verifying percentages:
|
|
248
|
-
# For biological domain:
|
|
249
|
-
bio_ok = returns_zero(bio_total, bio_test, bio_val)
|
|
250
|
-
# For physicochemical domain:
|
|
251
|
-
phch_ok = returns_zero(phch_total, phch_test, phch_val)
|
|
252
|
-
# For structural domain:
|
|
253
|
-
fp_ok = returns_zero(fp_total, fp_test, fp_val)
|
|
254
|
-
ok = [bio_ok, phch_ok, fp_ok]
|
|
255
|
-
max_iters = 0
|
|
256
|
-
|
|
257
|
-
# Redo the distribution in case of errors (up to 10 times):
|
|
258
|
-
while (True in ok) and (max_iters < 10):
|
|
259
|
-
# Split into training, test:
|
|
260
|
-
dataframe, test_or_val_molecules = MASSAsplit.split_train_test_sets(
|
|
261
|
-
dataframe, training_percent, splitting_strategy)
|
|
262
|
-
|
|
263
|
-
# Bar plot of frequencies (Calculates the percentages of molecules in each
|
|
264
|
-
# cluster for each dataset and generates a bar graph for each domain):
|
|
265
|
-
|
|
266
|
-
# Biological Bar Plot:
|
|
267
|
-
bio_total, bio_training, bio_test, bio_val = MASSAsplit.freq_clusters(
|
|
268
|
-
dataframe, directoryfile_output, extension_type,
|
|
269
|
-
'Cluster_Biological', barplot_xfont_size, splitting_strategy
|
|
270
|
-
)
|
|
271
|
-
# Physicochemical Bar Plot
|
|
272
|
-
phch_total, phch_training, phch_test, phch_val = MASSAsplit.freq_clusters(
|
|
273
|
-
dataframe, directoryfile_output, extension_type,
|
|
274
|
-
'Cluster_Physicochemical', barplot_xfont_size, splitting_strategy
|
|
275
|
-
)
|
|
276
|
-
# Structural Bar Plot
|
|
277
|
-
fp_total, fp_training, fp_test, fp_val = MASSAsplit.freq_clusters(
|
|
278
|
-
dataframe, directoryfile_output, extension_type,
|
|
279
|
-
'Cluster_Structural', barplot_xfont_size, splitting_strategy
|
|
280
|
-
)
|
|
281
|
-
# General Bar Plot
|
|
282
|
-
all_total, all_training, all_test, all_val = MASSAsplit.freq_clusters(
|
|
283
|
-
dataframe, directoryfile_output, extension_type,
|
|
284
|
-
'Cluster_General', barplot_xfont_size, splitting_strategy
|
|
285
|
-
)
|
|
286
|
-
|
|
287
|
-
# Verifying percentages:
|
|
288
|
-
|
|
289
|
-
# For biological domain:
|
|
290
|
-
bio_ok = returns_zero(bio_total, bio_test, bio_val)
|
|
291
|
-
# For physicochemical domain:
|
|
292
|
-
phch_ok = returns_zero(phch_total, phch_test, phch_val)
|
|
293
|
-
# For structural domain:
|
|
294
|
-
fp_ok = returns_zero(fp_total, fp_test, fp_val)
|
|
295
|
-
ok = [bio_ok, phch_ok, fp_ok]
|
|
296
|
-
max_iters += 1
|
|
297
|
-
|
|
298
|
-
# Write distribution information to log file:
|
|
299
|
-
bio_distr = 'Biological Distribution'
|
|
300
|
-
MASSAsplit.log_of_distributions(
|
|
301
|
-
bio_distr, bio_total, bio_training,
|
|
302
|
-
bio_test, bio_val, splitting_strategy,
|
|
303
|
-
write_log
|
|
304
|
-
)
|
|
305
|
-
phch_distr = 'Physicochemical Distribution'
|
|
306
|
-
MASSAsplit.log_of_distributions(
|
|
307
|
-
phch_distr, phch_total, phch_training,
|
|
308
|
-
phch_test, phch_val, splitting_strategy,
|
|
309
|
-
write_log
|
|
310
|
-
)
|
|
311
|
-
fp_distr = 'Structural (FP) Distribution'
|
|
312
|
-
MASSAsplit.log_of_distributions(
|
|
313
|
-
fp_distr, fp_total, fp_training,
|
|
314
|
-
fp_test, fp_val, splitting_strategy,
|
|
315
|
-
write_log
|
|
316
|
-
)
|
|
317
|
-
all_distr = 'General Distribution'
|
|
318
|
-
MASSAsplit.log_of_distributions(
|
|
319
|
-
all_distr, all_total, all_training,
|
|
320
|
-
all_test, all_val, splitting_strategy,
|
|
321
|
-
write_log
|
|
322
|
-
)
|
|
323
|
-
|
|
324
|
-
# Output management:
|
|
325
|
-
# It adds, for each molecule, the values of the calculated properties, the identifications of each cluster and which set the molecule belongs to.
|
|
326
|
-
out_name = working_directory + job_name
|
|
327
|
-
out_mols = MASSAmoloutput.output_file_mols(dataframe, out_name)
|
|
328
|
-
|
|
329
|
-
# Plot HCAs:
|
|
330
|
-
if flag_dendrogram == True:
|
|
331
|
-
print('\nGenerating dendrogram images. Please wait...')
|
|
332
|
-
MASSAcluster.hca_plot(
|
|
333
|
-
linkage_bio, names, leaves_cluster_bio,
|
|
334
|
-
cutoff_bio, 'bio', directoryfile_output,
|
|
335
|
-
extension_type, dendrogram_xfont_size, test_or_val_molecules
|
|
336
|
-
) # Bio_Plot: Plot the HCA dendrogram
|
|
337
|
-
MASSAcluster.hca_plot(
|
|
338
|
-
linkage_phch, names, leaves_cluster_phch,
|
|
339
|
-
cutoff_phch, 'PhCh', directoryfile_output,
|
|
340
|
-
extension_type, dendrogram_xfont_size, test_or_val_molecules
|
|
341
|
-
) # phch_Plot: Plot the HCA dendrogram
|
|
342
|
-
MASSAcluster.hca_plot(
|
|
343
|
-
linkage_fp, names, leaves_cluster_fp,
|
|
344
|
-
cutoff_fp, 'FP', directoryfile_output,
|
|
345
|
-
extension_type, dendrogram_xfont_size, test_or_val_molecules
|
|
346
|
-
) # fp_Plot: Plot the HCA dendrogram
|
|
347
|
-
|
|
348
|
-
end_time = time.time()
|
|
349
|
-
elapsed_time = end_time - start_time
|
|
350
|
-
write_log.write(f'Completed! Elapsed time = {elapsed_time} s.')
|
|
351
|
-
write_log.close()
|
|
352
|
-
print(f'Completed! Elapsed time = {elapsed_time} s.')
|
|
353
|
-
return out_mols
|
|
1
|
+
from MASSA_Algorithm import MASSAlogos
|
|
2
|
+
from MASSA_Algorithm import MASSAargs
|
|
3
|
+
from MASSA_Algorithm import MASSAod
|
|
4
|
+
from MASSA_Algorithm import MASSAopen_files
|
|
5
|
+
from MASSA_Algorithm import MASSAextraction
|
|
6
|
+
from MASSA_Algorithm import MASSAdescriptors
|
|
7
|
+
from MASSA_Algorithm import MASSApreparation
|
|
8
|
+
from MASSA_Algorithm import MASSAcluster
|
|
9
|
+
from MASSA_Algorithm import MASSAsplit
|
|
10
|
+
from MASSA_Algorithm import MASSAmoloutput
|
|
11
|
+
import time
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def returns_zero(total, test, validation):
|
|
15
|
+
"""
|
|
16
|
+
Description:
|
|
17
|
+
It evaluates whether the distribution is inadequate. That is,
|
|
18
|
+
when the iterated cluster has a percentage greater than 0.5%
|
|
19
|
+
in the complete dataset but less than 0.5% in the test set.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
total (dict):
|
|
23
|
+
Percentage of molecules in each cluster for the whole dataset.
|
|
24
|
+
|
|
25
|
+
test (dict):
|
|
26
|
+
Percentage of molecules in each cluster for the test subset.
|
|
27
|
+
|
|
28
|
+
validation (dict):
|
|
29
|
+
Percentage of molecules in each cluster for the validation subset.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
definer (boolean): Returns True if the distribution is
|
|
33
|
+
inadequate, and False if it is adequate.
|
|
34
|
+
"""
|
|
35
|
+
definer = False
|
|
36
|
+
for i in total.keys():
|
|
37
|
+
if (total[i] > 0.5) and (test[i] <= 0.5):
|
|
38
|
+
# Definer = True (Distribution was not done properly).
|
|
39
|
+
definer = True
|
|
40
|
+
elif validation != None:
|
|
41
|
+
if (total[i] > 0.5) and (validation[i] <= 0.5):
|
|
42
|
+
definer = True
|
|
43
|
+
return definer
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def py_massa(
|
|
47
|
+
file_input=str(),
|
|
48
|
+
working_directory=str(),
|
|
49
|
+
job_name="MASSAoutput.sdf",
|
|
50
|
+
extension_type="svg",
|
|
51
|
+
dendrogram_xfont_size=5,
|
|
52
|
+
barplot_xfont_size=9,
|
|
53
|
+
training_percent=round(float(0.8), 3),
|
|
54
|
+
bioactivities_as_args=None,
|
|
55
|
+
npcs=0.85,
|
|
56
|
+
svd_parameter="full",
|
|
57
|
+
linkage_method="complete",
|
|
58
|
+
flag_dendrogram=True,
|
|
59
|
+
splitting_strategy="tt",
|
|
60
|
+
drop_errors=True,
|
|
61
|
+
large_library="auto"
|
|
62
|
+
):
|
|
63
|
+
# Initializing from Python.
|
|
64
|
+
# Print the program logo:
|
|
65
|
+
MASSAlogos.python_logo()
|
|
66
|
+
start_time = time.time()
|
|
67
|
+
|
|
68
|
+
# Defining the working_directory alias:
|
|
69
|
+
working_directory = f"{working_directory}/"
|
|
70
|
+
directoryfile_output = working_directory
|
|
71
|
+
|
|
72
|
+
# It creates the output directories:
|
|
73
|
+
MASSAod.output_directory(directoryfile_output, flag_dendrogram)
|
|
74
|
+
|
|
75
|
+
# Test nPCs:
|
|
76
|
+
if npcs > 1:
|
|
77
|
+
npcs = int(npcs)
|
|
78
|
+
elif (npcs > 0) and (npcs <= 1):
|
|
79
|
+
npcs = float(npcs)
|
|
80
|
+
else:
|
|
81
|
+
raise ValueError(
|
|
82
|
+
f"ERROR: The defined number of main components is invalid. npcs = {str(npcs)}")
|
|
83
|
+
|
|
84
|
+
# Autodetect if the biological activities are set.
|
|
85
|
+
if isinstance(bioactivities_as_args, str):
|
|
86
|
+
number_bioact = 1
|
|
87
|
+
bioactivities_as_args = [bioactivities_as_args]
|
|
88
|
+
elif isinstance(bioactivities_as_args, list):
|
|
89
|
+
number_bioact = len(bioactivities_as_args)
|
|
90
|
+
elif bioactivities_as_args == None:
|
|
91
|
+
raise ValueError(
|
|
92
|
+
"The biological activities are not specified. bioactivities_as_args == None")
|
|
93
|
+
|
|
94
|
+
# Create log.txt file in directory:
|
|
95
|
+
log_path = directoryfile_output+'log.txt'
|
|
96
|
+
write_log = open(log_path, 'w')
|
|
97
|
+
|
|
98
|
+
if isinstance(file_input, str):
|
|
99
|
+
# Initial file management:
|
|
100
|
+
# Read molecules.
|
|
101
|
+
mols = MASSAopen_files.read_molecules(
|
|
102
|
+
file_input, write_log, drop_errors)
|
|
103
|
+
else:
|
|
104
|
+
mols = file_input
|
|
105
|
+
|
|
106
|
+
# Test if large_library is set:
|
|
107
|
+
if isinstance(large_library, str):
|
|
108
|
+
if large_library.lower() == 'true':
|
|
109
|
+
large_library = True
|
|
110
|
+
elif large_library.lower() == 'false':
|
|
111
|
+
large_library = False
|
|
112
|
+
elif large_library.lower() == 'auto':
|
|
113
|
+
if int(len(mols)) > 9999:
|
|
114
|
+
large_library = True
|
|
115
|
+
else:
|
|
116
|
+
large_library = False
|
|
117
|
+
|
|
118
|
+
# If auto detection is enable to select the initial cluster algorithm.
|
|
119
|
+
if large_library == 'auto':
|
|
120
|
+
if int(len(mols)) > 9999:
|
|
121
|
+
large_library = True
|
|
122
|
+
else:
|
|
123
|
+
large_library = False
|
|
124
|
+
|
|
125
|
+
if large_library == True:
|
|
126
|
+
# Deactivates the HCA dendrogram.
|
|
127
|
+
flag_dendrogram = False
|
|
128
|
+
|
|
129
|
+
# Extracting the property names from the ".sdf" input file.
|
|
130
|
+
sdf_property_names = MASSAopen_files.get_sdf_property_names(mols)
|
|
131
|
+
# Structure 3D management - It adds hydrogens keeping 3D coordenates.
|
|
132
|
+
mols_h = MASSAopen_files.hydrogen_add(mols)
|
|
133
|
+
|
|
134
|
+
# Extraction properties from ".sdf":
|
|
135
|
+
# It extracts the names of the molecules and creates a name:molecule dictionary and a dataframe.
|
|
136
|
+
names, dataframe = MASSAextraction.name_extraction(mols_h)
|
|
137
|
+
|
|
138
|
+
# It defines a list of what biological activities are being extracted.
|
|
139
|
+
biological_activity = MASSAextraction.the_biological_handler(
|
|
140
|
+
sdf_property_names, number_bioact, bioactivities_as_args)
|
|
141
|
+
# It adds the biological activities to the dataframe.
|
|
142
|
+
dataframe = MASSAextraction.list_activities(dataframe, biological_activity)
|
|
143
|
+
|
|
144
|
+
# Get fingeprint and other descriptors:
|
|
145
|
+
# Get physicochemical descriptors.
|
|
146
|
+
dataframe = MASSAdescriptors.physicochemical_descriptors(dataframe)
|
|
147
|
+
# Get AtomPairs fingerprint.
|
|
148
|
+
dataframe = MASSAdescriptors.atompairs_fingerprint(dataframe)
|
|
149
|
+
|
|
150
|
+
# Normalizes physicochemical and biological properties.
|
|
151
|
+
# Creates matrices for the three domains (struc, phys-chem, bio):
|
|
152
|
+
bio_matrix, phch_matrix, fp_matrix = MASSApreparation.normalizer_or_matrix(
|
|
153
|
+
dataframe, biological_activity)
|
|
154
|
+
|
|
155
|
+
# PCA:
|
|
156
|
+
# PCA for the biological domain.
|
|
157
|
+
bio_pca = MASSApreparation.pca_maker(bio_matrix, npcs, svd_parameter)
|
|
158
|
+
# PCA for the physicochemical domain.
|
|
159
|
+
phch_pca = MASSApreparation.pca_maker(phch_matrix, npcs, svd_parameter)
|
|
160
|
+
# PCA for the structural domain.
|
|
161
|
+
fp_pca = MASSApreparation.pca_maker(fp_matrix, npcs, svd_parameter)
|
|
162
|
+
|
|
163
|
+
if large_library == True:
|
|
164
|
+
# First clustering (MiniBatch-KMeans):
|
|
165
|
+
# It performs KMeans clustering for the biological domain.
|
|
166
|
+
bio_hca = MASSAcluster.kmeans_clusters(
|
|
167
|
+
bio_pca, names, 'bio', directoryfile_output, extension_type)
|
|
168
|
+
# It performs KMeans clustering for the physicochemical domain.
|
|
169
|
+
phch_hca = MASSAcluster.kmeans_clusters(
|
|
170
|
+
phch_pca, names, 'PhCh', directoryfile_output, extension_type)
|
|
171
|
+
# It performs KMeans clustering for the structural domain.
|
|
172
|
+
fp_hca = MASSAcluster.kmeans_clusters(
|
|
173
|
+
fp_pca, names, 'FP', directoryfile_output, extension_type)
|
|
174
|
+
else:
|
|
175
|
+
# First clustering (HCA):
|
|
176
|
+
# It performs HCA clustering without generating the dendrogram for the biological domain.
|
|
177
|
+
leaves_cluster_bio, bio_hca, linkage_bio, cutoff_bio = MASSAcluster.hca_clusters(
|
|
178
|
+
bio_pca, names, 'bio', directoryfile_output, extension_type, linkage_method)
|
|
179
|
+
# It performs HCA clustering without generating the dendrogram for the physicochemical domain.
|
|
180
|
+
leaves_cluster_phch, phch_hca, linkage_phch, cutoff_phch = MASSAcluster.hca_clusters(
|
|
181
|
+
phch_pca, names, 'PhCh', directoryfile_output, extension_type, linkage_method)
|
|
182
|
+
# It performs HCA clustering without generating the dendrogram for the structural domain.
|
|
183
|
+
leaves_cluster_fp, fp_hca, linkage_fp, cutoff_fp = MASSAcluster.hca_clusters(
|
|
184
|
+
fp_pca, names, 'FP', directoryfile_output, extension_type, linkage_method)
|
|
185
|
+
|
|
186
|
+
# It adds the biological cluster identification to the spreadsheet.
|
|
187
|
+
dataframe = MASSApreparation.organize_df_clusterization(
|
|
188
|
+
dataframe, bio_hca, 'bio')
|
|
189
|
+
# It adds the physicochemical cluster identification to the spreadsheet.
|
|
190
|
+
dataframe = MASSApreparation.organize_df_clusterization(
|
|
191
|
+
dataframe, phch_hca, 'PhCh')
|
|
192
|
+
# It adds the structural cluster identification to the spreadsheet.
|
|
193
|
+
dataframe = MASSApreparation.organize_df_clusterization(
|
|
194
|
+
dataframe, fp_hca, 'FP')
|
|
195
|
+
|
|
196
|
+
# Second clustering (Kmodes):
|
|
197
|
+
# It creates a matrix with cluster identifications for each of the three domains for Kmodes.
|
|
198
|
+
matrix_for_kmodes = MASSApreparation.organize_for_kmodes(dataframe)
|
|
199
|
+
# It performs Kmodes clustering for the general domain.
|
|
200
|
+
all_hca = MASSAcluster.kmodes_clusters(matrix_for_kmodes, names,
|
|
201
|
+
directoryfile_output, extension_type)
|
|
202
|
+
# It adds the general cluster identification to the spreadsheet.
|
|
203
|
+
dataframe = MASSApreparation.organize_df_clusterization(
|
|
204
|
+
dataframe, all_hca, 'all')
|
|
205
|
+
|
|
206
|
+
# Split into training, test:
|
|
207
|
+
dataframe, test_or_val_molecules = MASSAsplit.split_train_test_sets(
|
|
208
|
+
dataframe, training_percent, splitting_strategy)
|
|
209
|
+
|
|
210
|
+
# Bar plot of frequencies
|
|
211
|
+
# (Calculates the percentages of molecules in each cluster for each
|
|
212
|
+
# dataset and generates a bar graph for each domain):
|
|
213
|
+
|
|
214
|
+
# Biological Bar Plot
|
|
215
|
+
bio_total, bio_training, bio_test, bio_val = MASSAsplit.freq_clusters(
|
|
216
|
+
dataframe,
|
|
217
|
+
directoryfile_output,
|
|
218
|
+
extension_type,
|
|
219
|
+
'Cluster_Biological',
|
|
220
|
+
barplot_xfont_size,
|
|
221
|
+
splitting_strategy)
|
|
222
|
+
# Physicochemical Bar Plot
|
|
223
|
+
phch_total, phch_training, phch_test, phch_val = MASSAsplit.freq_clusters(
|
|
224
|
+
dataframe,
|
|
225
|
+
directoryfile_output,
|
|
226
|
+
extension_type,
|
|
227
|
+
'Cluster_Physicochemical',
|
|
228
|
+
barplot_xfont_size,
|
|
229
|
+
splitting_strategy)
|
|
230
|
+
# Structural Bar Plot
|
|
231
|
+
fp_total, fp_training, fp_test, fp_val = MASSAsplit.freq_clusters(
|
|
232
|
+
dataframe,
|
|
233
|
+
directoryfile_output,
|
|
234
|
+
extension_type,
|
|
235
|
+
'Cluster_Structural',
|
|
236
|
+
barplot_xfont_size,
|
|
237
|
+
splitting_strategy)
|
|
238
|
+
# General Bar Plot
|
|
239
|
+
all_total, all_training, all_test, all_val = MASSAsplit.freq_clusters(
|
|
240
|
+
dataframe,
|
|
241
|
+
directoryfile_output,
|
|
242
|
+
extension_type,
|
|
243
|
+
'Cluster_General',
|
|
244
|
+
barplot_xfont_size,
|
|
245
|
+
splitting_strategy)
|
|
246
|
+
|
|
247
|
+
# Verifying percentages:
|
|
248
|
+
# For biological domain:
|
|
249
|
+
bio_ok = returns_zero(bio_total, bio_test, bio_val)
|
|
250
|
+
# For physicochemical domain:
|
|
251
|
+
phch_ok = returns_zero(phch_total, phch_test, phch_val)
|
|
252
|
+
# For structural domain:
|
|
253
|
+
fp_ok = returns_zero(fp_total, fp_test, fp_val)
|
|
254
|
+
ok = [bio_ok, phch_ok, fp_ok]
|
|
255
|
+
max_iters = 0
|
|
256
|
+
|
|
257
|
+
# Redo the distribution in case of errors (up to 10 times):
|
|
258
|
+
while (True in ok) and (max_iters < 10):
|
|
259
|
+
# Split into training, test:
|
|
260
|
+
dataframe, test_or_val_molecules = MASSAsplit.split_train_test_sets(
|
|
261
|
+
dataframe, training_percent, splitting_strategy)
|
|
262
|
+
|
|
263
|
+
# Bar plot of frequencies (Calculates the percentages of molecules in each
|
|
264
|
+
# cluster for each dataset and generates a bar graph for each domain):
|
|
265
|
+
|
|
266
|
+
# Biological Bar Plot:
|
|
267
|
+
bio_total, bio_training, bio_test, bio_val = MASSAsplit.freq_clusters(
|
|
268
|
+
dataframe, directoryfile_output, extension_type,
|
|
269
|
+
'Cluster_Biological', barplot_xfont_size, splitting_strategy
|
|
270
|
+
)
|
|
271
|
+
# Physicochemical Bar Plot
|
|
272
|
+
phch_total, phch_training, phch_test, phch_val = MASSAsplit.freq_clusters(
|
|
273
|
+
dataframe, directoryfile_output, extension_type,
|
|
274
|
+
'Cluster_Physicochemical', barplot_xfont_size, splitting_strategy
|
|
275
|
+
)
|
|
276
|
+
# Structural Bar Plot
|
|
277
|
+
fp_total, fp_training, fp_test, fp_val = MASSAsplit.freq_clusters(
|
|
278
|
+
dataframe, directoryfile_output, extension_type,
|
|
279
|
+
'Cluster_Structural', barplot_xfont_size, splitting_strategy
|
|
280
|
+
)
|
|
281
|
+
# General Bar Plot
|
|
282
|
+
all_total, all_training, all_test, all_val = MASSAsplit.freq_clusters(
|
|
283
|
+
dataframe, directoryfile_output, extension_type,
|
|
284
|
+
'Cluster_General', barplot_xfont_size, splitting_strategy
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
# Verifying percentages:
|
|
288
|
+
|
|
289
|
+
# For biological domain:
|
|
290
|
+
bio_ok = returns_zero(bio_total, bio_test, bio_val)
|
|
291
|
+
# For physicochemical domain:
|
|
292
|
+
phch_ok = returns_zero(phch_total, phch_test, phch_val)
|
|
293
|
+
# For structural domain:
|
|
294
|
+
fp_ok = returns_zero(fp_total, fp_test, fp_val)
|
|
295
|
+
ok = [bio_ok, phch_ok, fp_ok]
|
|
296
|
+
max_iters += 1
|
|
297
|
+
|
|
298
|
+
# Write distribution information to log file:
|
|
299
|
+
bio_distr = 'Biological Distribution'
|
|
300
|
+
MASSAsplit.log_of_distributions(
|
|
301
|
+
bio_distr, bio_total, bio_training,
|
|
302
|
+
bio_test, bio_val, splitting_strategy,
|
|
303
|
+
write_log
|
|
304
|
+
)
|
|
305
|
+
phch_distr = 'Physicochemical Distribution'
|
|
306
|
+
MASSAsplit.log_of_distributions(
|
|
307
|
+
phch_distr, phch_total, phch_training,
|
|
308
|
+
phch_test, phch_val, splitting_strategy,
|
|
309
|
+
write_log
|
|
310
|
+
)
|
|
311
|
+
fp_distr = 'Structural (FP) Distribution'
|
|
312
|
+
MASSAsplit.log_of_distributions(
|
|
313
|
+
fp_distr, fp_total, fp_training,
|
|
314
|
+
fp_test, fp_val, splitting_strategy,
|
|
315
|
+
write_log
|
|
316
|
+
)
|
|
317
|
+
all_distr = 'General Distribution'
|
|
318
|
+
MASSAsplit.log_of_distributions(
|
|
319
|
+
all_distr, all_total, all_training,
|
|
320
|
+
all_test, all_val, splitting_strategy,
|
|
321
|
+
write_log
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
# Output management:
|
|
325
|
+
# It adds, for each molecule, the values of the calculated properties, the identifications of each cluster and which set the molecule belongs to.
|
|
326
|
+
out_name = working_directory + job_name
|
|
327
|
+
out_mols = MASSAmoloutput.output_file_mols(dataframe, out_name)
|
|
328
|
+
|
|
329
|
+
# Plot HCAs:
|
|
330
|
+
if flag_dendrogram == True:
|
|
331
|
+
print('\nGenerating dendrogram images. Please wait...')
|
|
332
|
+
MASSAcluster.hca_plot(
|
|
333
|
+
linkage_bio, names, leaves_cluster_bio,
|
|
334
|
+
cutoff_bio, 'bio', directoryfile_output,
|
|
335
|
+
extension_type, dendrogram_xfont_size, test_or_val_molecules
|
|
336
|
+
) # Bio_Plot: Plot the HCA dendrogram
|
|
337
|
+
MASSAcluster.hca_plot(
|
|
338
|
+
linkage_phch, names, leaves_cluster_phch,
|
|
339
|
+
cutoff_phch, 'PhCh', directoryfile_output,
|
|
340
|
+
extension_type, dendrogram_xfont_size, test_or_val_molecules
|
|
341
|
+
) # phch_Plot: Plot the HCA dendrogram
|
|
342
|
+
MASSAcluster.hca_plot(
|
|
343
|
+
linkage_fp, names, leaves_cluster_fp,
|
|
344
|
+
cutoff_fp, 'FP', directoryfile_output,
|
|
345
|
+
extension_type, dendrogram_xfont_size, test_or_val_molecules
|
|
346
|
+
) # fp_Plot: Plot the HCA dendrogram
|
|
347
|
+
|
|
348
|
+
end_time = time.time()
|
|
349
|
+
elapsed_time = end_time - start_time
|
|
350
|
+
write_log.write(f'Completed! Elapsed time = {elapsed_time} s.')
|
|
351
|
+
write_log.close()
|
|
352
|
+
print(f'Completed! Elapsed time = {elapsed_time} s.')
|
|
353
|
+
return out_mols
|