D4CMPP2 0.4.0__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.
Files changed (103) hide show
  1. D4CMPP2/_Data/AGENTS.md +24 -0
  2. D4CMPP2/_Data/Aqsoldb.csv +9291 -0
  3. D4CMPP2/_Data/BradleyMP.csv +3042 -0
  4. D4CMPP2/_Data/Lipophilicity.csv +1131 -0
  5. D4CMPP2/_Data/README.md +8 -0
  6. D4CMPP2/_Data/__init__.py +26 -0
  7. D4CMPP2/_Data/optical.csv +20237 -0
  8. D4CMPP2/_Data/test.csv +190 -0
  9. D4CMPP2/__init__.py +16 -0
  10. D4CMPP2/__main__.py +5 -0
  11. D4CMPP2/_main.py +500 -0
  12. D4CMPP2/cli.py +7 -0
  13. D4CMPP2/exceptions.py +53 -0
  14. D4CMPP2/grid_search.py +259 -0
  15. D4CMPP2/network_refer.yaml +160 -0
  16. D4CMPP2/networks/AFP_model.py +72 -0
  17. D4CMPP2/networks/AFPwithSolv_model.py +72 -0
  18. D4CMPP2/networks/DMPNN_model.py +90 -0
  19. D4CMPP2/networks/DMPNNwithSolv_model.py +89 -0
  20. D4CMPP2/networks/GAT_model.py +48 -0
  21. D4CMPP2/networks/GATwithSolv_model.py +63 -0
  22. D4CMPP2/networks/GCN_model.py +113 -0
  23. D4CMPP2/networks/GCNwithSolv_model.py +103 -0
  24. D4CMPP2/networks/GC_model.py +122 -0
  25. D4CMPP2/networks/ISATPM_model.py +14 -0
  26. D4CMPP2/networks/ISATPN_model.py +199 -0
  27. D4CMPP2/networks/ISAT_model.py +90 -0
  28. D4CMPP2/networks/MPNN_model.py +56 -0
  29. D4CMPP2/networks/MPNNwithSolv_model.py +72 -0
  30. D4CMPP2/networks/__init__.py +25 -0
  31. D4CMPP2/networks/base.py +250 -0
  32. D4CMPP2/networks/registry.py +187 -0
  33. D4CMPP2/networks/src/AFP.py +118 -0
  34. D4CMPP2/networks/src/BiDropout.py +29 -0
  35. D4CMPP2/networks/src/DMPNN.py +35 -0
  36. D4CMPP2/networks/src/GAT.py +69 -0
  37. D4CMPP2/networks/src/GC.py +85 -0
  38. D4CMPP2/networks/src/GCN.py +71 -0
  39. D4CMPP2/networks/src/ISAT.py +153 -0
  40. D4CMPP2/networks/src/Linear.py +49 -0
  41. D4CMPP2/networks/src/MPNN.py +56 -0
  42. D4CMPP2/networks/src/SolventLayer.py +62 -0
  43. D4CMPP2/networks/src/__init__.py +0 -0
  44. D4CMPP2/networks/src/distGCN.py +21 -0
  45. D4CMPP2/networks/src/pyg_hetero.py +24 -0
  46. D4CMPP2/optimize.py +472 -0
  47. D4CMPP2/src/Analyzer/ISAAnalyzer.py +458 -0
  48. D4CMPP2/src/Analyzer/ISAPNAnalyzer.py +366 -0
  49. D4CMPP2/src/Analyzer/ISAwSAnalyzer.py +117 -0
  50. D4CMPP2/src/Analyzer/MolAnalyzer.py +319 -0
  51. D4CMPP2/src/Analyzer/__init__.py +54 -0
  52. D4CMPP2/src/Analyzer/core.py +480 -0
  53. D4CMPP2/src/Analyzer/factory.py +166 -0
  54. D4CMPP2/src/Analyzer/interpretation.py +232 -0
  55. D4CMPP2/src/Analyzer/results.py +101 -0
  56. D4CMPP2/src/DataManager/Dataset/GraphDataset.py +314 -0
  57. D4CMPP2/src/DataManager/Dataset/ISAGraphDataset.py +384 -0
  58. D4CMPP2/src/DataManager/Dataset/__init__.py +0 -0
  59. D4CMPP2/src/DataManager/GraphGenerator/ISAGraphGenerator.py +223 -0
  60. D4CMPP2/src/DataManager/GraphGenerator/MolGraphGenerator.py +73 -0
  61. D4CMPP2/src/DataManager/GraphGenerator/__init__.py +14 -0
  62. D4CMPP2/src/DataManager/ISADataManager.py +67 -0
  63. D4CMPP2/src/DataManager/MolDataManager.py +735 -0
  64. D4CMPP2/src/DataManager/__init__.py +14 -0
  65. D4CMPP2/src/DataManager/contracts.py +179 -0
  66. D4CMPP2/src/NetworkManager/ISANetworkManager.py +12 -0
  67. D4CMPP2/src/NetworkManager/NetworkManager.py +520 -0
  68. D4CMPP2/src/NetworkManager/__init__.py +14 -0
  69. D4CMPP2/src/PostProcessor.py +160 -0
  70. D4CMPP2/src/TrainManager/ISATrainManager.py +26 -0
  71. D4CMPP2/src/TrainManager/TrainManager.py +254 -0
  72. D4CMPP2/src/TrainManager/__init__.py +14 -0
  73. D4CMPP2/src/TrainManager/callbacks.py +119 -0
  74. D4CMPP2/src/__init__.py +0 -0
  75. D4CMPP2/src/utils/PATH.py +246 -0
  76. D4CMPP2/src/utils/__init__.py +0 -0
  77. D4CMPP2/src/utils/argparser.py +56 -0
  78. D4CMPP2/src/utils/checkpointing.py +90 -0
  79. D4CMPP2/src/utils/config_resolution.py +123 -0
  80. D4CMPP2/src/utils/config_validation.py +370 -0
  81. D4CMPP2/src/utils/csv_validation.py +105 -0
  82. D4CMPP2/src/utils/data_quality.py +181 -0
  83. D4CMPP2/src/utils/featureizer.py +202 -0
  84. D4CMPP2/src/utils/functional_group.csv +169 -0
  85. D4CMPP2/src/utils/graph_cache.py +213 -0
  86. D4CMPP2/src/utils/leaderboard.py +212 -0
  87. D4CMPP2/src/utils/metrics.py +31 -0
  88. D4CMPP2/src/utils/module_loader.py +147 -0
  89. D4CMPP2/src/utils/output.py +80 -0
  90. D4CMPP2/src/utils/reproducibility.py +70 -0
  91. D4CMPP2/src/utils/run_manifest.py +175 -0
  92. D4CMPP2/src/utils/scaler.py +40 -0
  93. D4CMPP2/src/utils/sculptor.py +713 -0
  94. D4CMPP2/src/utils/splitting.py +250 -0
  95. D4CMPP2/src/utils/supportfile_saver.py +94 -0
  96. D4CMPP2/src/utils/tools.py +156 -0
  97. D4CMPP2/src/utils/transfer_learning.py +111 -0
  98. d4cmpp2-0.4.0.dist-info/METADATA +420 -0
  99. d4cmpp2-0.4.0.dist-info/RECORD +103 -0
  100. d4cmpp2-0.4.0.dist-info/WHEEL +5 -0
  101. d4cmpp2-0.4.0.dist-info/entry_points.txt +2 -0
  102. d4cmpp2-0.4.0.dist-info/licenses/LICENSE +21 -0
  103. d4cmpp2-0.4.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,713 @@
1
+ from MoleculeSculptor.src.subgroup import Subgroup, Subgroup_list
2
+ from MoleculeSculptor.src.sculptor import Segmentator, SubgroupSplitter, SubgroupSplitter_for_DA
3
+
4
+
5
+
6
+
7
+ # import numpy as np
8
+ # from rdkit import Chem
9
+ # import sys
10
+ # import os
11
+ # import pandas as pd
12
+ # from . import PATH
13
+ # from .tools import showAtomHighlight
14
+ # import re
15
+
16
+ # module_path = os.path.abspath(os.path.join('..'))
17
+ # if module_path not in sys.path:
18
+ # sys.path.append(module_path)
19
+
20
+
21
+ # class Subgroup():
22
+ # "the unit of the fragmentation"
23
+ # def __init__(self, mol, atoms, name, priority):
24
+ # self.atoms=atoms
25
+ # self.name=name
26
+ # self.priority=str(priority)
27
+ # self.mol = mol if type(mol)==Chem.rdchem.Mol else Chem.MolFromSmiles(mol)
28
+ # for atom in mol.GetAtoms():
29
+ # atom.SetAtomMapNum(atom.GetIdx()+1)
30
+
31
+
32
+ # def __len__(self):
33
+ # return len(self.atoms)
34
+
35
+ # def add_smiles(self,thrsh=4):
36
+ # group_smiles = self.specify_group()
37
+ # if group_smiles is None: return
38
+ # if len(self.atoms)<=thrsh:
39
+ # self.smiles=group_smiles
40
+ # else:
41
+ # smi=Chem.MolFragmentToSmiles(self.mol,[int(j) for j in self.atoms])
42
+ # self.smiles=smi #remove_index(smi)
43
+ # # self.atoms = [int(i)-1 for i in re.findall(r'\:(\d+)\]',self.smiles)]
44
+
45
+ # def specify_group(self):
46
+ # # smiles=get_fragment_with_branch(self.mol,self.atoms)
47
+ # # if smiles =="*c1ccccc1":
48
+ # # self.name = "Phenyl"
49
+ # # self.smiles = "*c1ccccc1"
50
+ # # return None
51
+ # return get_fragment_with_branch(self.mol,self.atoms)
52
+
53
+
54
+ # class Subgroup_list():
55
+ # "the list of the subgroups for efficiently managing the subgroups"
56
+ # def __init__(self, mol, subgroups):
57
+ # self.subgroups = subgroups
58
+ # self.mol = mol if type(mol)==Chem.rdchem.Mol else Chem.MolFromSmiles(mol)
59
+
60
+ # # 그룹 인접행렬 생성
61
+ # adj_mat = np.eye(len(subgroups))
62
+ # for i in range(len(subgroups)):
63
+ # for j in range(i+1,len(subgroups)):
64
+ # sub1,sub2=subgroups[i],subgroups[j]
65
+ # if is_neighbor(self.mol,sub1.atoms,sub2.atoms):
66
+ # adj_mat[i,j]=1
67
+ # adj_mat[j,i]=1
68
+ # self.adj_mat=adj_mat
69
+
70
+ # def __len__(self):
71
+ # return len(self.subgroups)
72
+
73
+ # def __getitem__(self, key):
74
+ # return self.subgroups[key]
75
+
76
+ # def __iter__(self):
77
+ # return iter(self.subgroups)
78
+
79
+ # def is_neighbor(self,i,j):
80
+ # return self.adj_mat[i,j]==1
81
+
82
+ # def concat(self,idxs_list,order = '8'):
83
+ # if type(idxs_list)!=list: idxs_list=[idxs_list]
84
+ # if type(order) != list: order = [order]*len(idxs_list)
85
+ # elif len(order)!=len(idxs_list):
86
+ # raise Exception("Error: order length must be equal to idxs_list length")
87
+
88
+ # delete_idx = []
89
+ # for idxs, _order in zip(idxs_list,order):
90
+ # if len(idxs)==1: continue
91
+ # i = idxs[0]
92
+ # for j in idxs[1:]:
93
+ # self.subgroups[i].atoms = list(np.concatenate([self.subgroups[i].atoms,self.subgroups[j].atoms]))
94
+ # self.subgroups[i].name = self.subgroups[i].name+'+'+self.subgroups[j].name
95
+ # self.subgroups[i].priority = _order
96
+
97
+ # self.adj_mat[i,:]=((self.adj_mat[i,:]+self.adj_mat[j,:])>0)*1
98
+ # self.adj_mat[:,i]=((self.adj_mat[:,i]+self.adj_mat[:,j])>0)*1
99
+
100
+ # delete_idx.append(j)
101
+ # delete_idx = list(set(delete_idx))
102
+ # if len(delete_idx)==0: return
103
+ # self.adj_mat=np.delete(self.adj_mat,delete_idx,axis=0)
104
+ # self.adj_mat=np.delete(self.adj_mat,delete_idx,axis=1)
105
+ # for j in [self.subgroups[i] for i in delete_idx]:
106
+ # self.subgroups.remove(j)
107
+
108
+ # def get_num_outter_bond(self, idx):
109
+ # # args| idx (int) : the index of the subgroup
110
+ # # return| list of int : the number of the outter bond of the atoms in the subgroup
111
+ # num_list = []
112
+ # for a in self.subgroups[idx].atoms:
113
+ # count=0
114
+ # atom = self.mol.GetAtomWithIdx(int(a))
115
+ # for n in atom.GetNeighbors():
116
+ # if n.GetIdx() not in self.subgroups[idx].atoms:
117
+ # count+=1
118
+ # num_list.append(count)
119
+ # return num_list
120
+
121
+ # def get_atm_idx_of_outter_bond(self,idx):
122
+ # # args: idx (int) : the index of the subgroup
123
+ # # return: list of list of int: the index of destination atoms of the outter bond of the atoms in the subgroup
124
+ # dest_idx_list = []
125
+ # for a in self.subgroups[idx].atoms:
126
+ # atom = self.mol.GetAtomWithIdx(int(a))
127
+ # outter_atom = []
128
+ # for n in atom.GetNeighbors():
129
+ # if n.GetIdx() not in self.subgroups[idx].atoms:
130
+ # outter_atom.append(n.GetIdx())
131
+ # dest_idx_list.append(outter_atom)
132
+ # return dest_idx_list
133
+
134
+ # def get_group_idx_of_outter_bond(self,idx):
135
+ # # args: idx (int) : the index of the subgroup
136
+ # # return: list of list of int: the index of destination atoms of the outter bond of the atoms in the subgroup
137
+ # dest_idx_list = []
138
+ # for a in self.subgroups[idx].atoms:
139
+ # atom = self.mol.GetAtomWithIdx(int(a))
140
+ # outter_atom = []
141
+ # for n in atom.GetNeighbors():
142
+ # if n.GetIdx() not in self.subgroups[idx].atoms:
143
+ # outter_atom.append(self.get_parent_group_of_atom(n.GetIdx()))
144
+ # dest_idx_list.append(outter_atom)
145
+ # return dest_idx_list
146
+
147
+ # def get_parent_group_of_atom(self,atom_idx):
148
+ # # args: atom_idx (int) : the index of the atom
149
+ # # return: int : the index of the parent group of the atom
150
+ # for i,subgroup in enumerate(self.subgroups):
151
+ # if atom_idx in subgroup.atoms:
152
+ # return i
153
+
154
+
155
+ # class Segmentator():
156
+ # "the class for the Segmentation"
157
+ # def __init__(self, s, c, a, combine_overlapped_ring=True):
158
+ # """
159
+ # Args:
160
+ # s : int
161
+ # the order of the split
162
+ # c : int
163
+ # the order of the combine
164
+ # a : int
165
+ # the order of the assimilation
166
+ # combine_overlapped_ring: bool. Default is True
167
+ # if True, the overlapped rings will be combined
168
+
169
+ # """
170
+ # self.ss = SubgroupSplitter(PATH.init_frag_ref_path({}),
171
+ # split_order=s,
172
+ # combine_rest_order=c,
173
+ # absorb_neighbor_order=a,
174
+ # overlapped_ring_combine=combine_overlapped_ring)
175
+
176
+ # def segment(self, mol, get_only_index=False, draw=False, star_threshold = 4, concat_double_bond_with_ring=False):
177
+ # """
178
+ # Args:
179
+ # mol: str or Chem.rdchem.Mol
180
+ # the molecule to segment
181
+ # get_only_index: bool. Default is False
182
+ # if True, the index of the atoms will be returned
183
+ # if False, the Subgroup objects will be returned
184
+ # draw: bool. Default is False
185
+ # if True, the molecule with the highlighted atoms will be drawn
186
+ # ----------------------------------------------
187
+ # Returns:
188
+ # list of list of int or Subgroup_list
189
+ # """
190
+ # return self.ss.fragmentation_with_condition(mol,get_index=get_only_index,draw=draw,star_threshold = star_threshold, concat_double_bond_with_ring=concat_double_bond_with_ring)
191
+
192
+
193
+ # class SubgroupSplitter(object):
194
+ # def __init__(self, refer_path=None,
195
+ # split_order=6,
196
+ # combine_rest_order=1,
197
+ # absorb_neighbor_order=-1,
198
+
199
+ # overlapped_ring_combine=True,
200
+ # log=False,
201
+ # draw=False,
202
+ # get_index=False
203
+ # ):
204
+ # #self.smiles_list = smiles_list
205
+ # if refer_path is None:
206
+ # refer_path = os.path.join(PATH.base_dir,"src/utils/functional_group.csv")
207
+ # path = os.path.join(refer_path)
208
+ # data_from = os.path.realpath(path)
209
+ # df = pd.read_csv(data_from, header=0)
210
+ # pattern = np.array([df['Name'], df['SMARTS'], df['Priority']])
211
+ # self.sorted_pattern = pattern[:, np.argsort(pattern[2, :])]
212
+ # self.frag_name_list = list(dict.fromkeys(self.sorted_pattern[0, :]))
213
+ # self.frag_dim=167
214
+
215
+ # self.split_order=split_order
216
+ # self.overlapped_ring_combine=overlapped_ring_combine
217
+ # self.combine_rest_order=combine_rest_order
218
+ # self.absorb_neighbor_order=absorb_neighbor_order
219
+ # self.log=log
220
+ # self.draw=draw
221
+ # self.get_index=get_index
222
+ # self.adj_mat = None
223
+
224
+ # def fragmentation_with_condition(self,mol,
225
+ # split_order=None,
226
+ # overlapped_ring_combine=None,
227
+ # combine_rest_order=None,
228
+ # absorb_neighbor_order=None,
229
+ # log=None,
230
+ # draw=None,
231
+ # get_index=None,
232
+ # atom_with_index=False,
233
+ # star_threshold=4,
234
+ # concat_double_bond_with_ring=False):
235
+ # if split_order is None: split_order=self.split_order
236
+ # if overlapped_ring_combine is None: overlapped_ring_combine=self.overlapped_ring_combine
237
+ # if combine_rest_order is None: combine_rest_order=self.combine_rest_order
238
+ # if absorb_neighbor_order is None: absorb_neighbor_order=self.absorb_neighbor_order
239
+ # if log is None: log=self.log
240
+ # if draw is None: draw=self.draw
241
+ # if get_index is None: get_index=self.get_index
242
+ # self.subgroup_list = None
243
+
244
+
245
+ # if type(mol)==str: mol = Chem.MolFromSmiles(mol)
246
+ # self.mol_size = mol.GetNumAtoms()
247
+ # self.mol=mol
248
+ # pat_list = self.get_pattern_list(mol)
249
+
250
+ # # 분자내의 모든 패턴을 찾음
251
+ # layer_pat_list,layer_sorted_pattern = self.get_masked_pattern_list(pat_list,order=split_order)
252
+
253
+ # # 찾은 패턴 중 유효한 패턴을 찾음
254
+ # self.init_subgroup_list(layer_pat_list,layer_sorted_pattern,
255
+ # log=log,ring_combine=overlapped_ring_combine,mol=mol)
256
+
257
+ # # 이중결합이 있는 그룹이 고리와 이웃한 경우 합침
258
+ # if concat_double_bond_with_ring:
259
+ # self.combine_double_bond_with_ring()
260
+
261
+ # # 이웃하는 패턴끼리 합침
262
+ # if combine_rest_order>0:
263
+ # self.combine_neighbor_subgroups(order=combine_rest_order,log=log)
264
+
265
+ # # 주변 고리패턴에 흡수됨
266
+ # if absorb_neighbor_order>0:
267
+ # self.absorb_neighbor_subgroups(order=absorb_neighbor_order,log=log)
268
+
269
+ # return self.return_result(log,draw,get_index,atom_with_index,star_threshold)
270
+
271
+ # def return_result(self,log=False,draw=False,get_index=False,atom_with_index=True,star_threshold=4):
272
+ # atoms = []
273
+ # for i in self.subgroup_list:
274
+ # for j in self.subgroup_list:
275
+ # if i==j: continue
276
+ # if set(i.atoms).intersection(set(j.atoms)):
277
+ # raise Exception("Error: overlapped subgroup\n",i.atoms,j.atoms)
278
+ # atoms+=i.atoms
279
+ # if len(atoms)!=self.mol_size:
280
+ # raise Exception("Error: not matched subgroup\n",atoms)
281
+
282
+ # if log:
283
+ # print("return_result")
284
+ # print([(i.name,i.atoms,) for i in self.subgroup_list])
285
+ # if draw:
286
+ # hit_atom_list = [list2int(i.atoms) for i in self.subgroup_list]
287
+ # showAtomHighlight(self.mol,hit_atom_list,atom_with_index=atom_with_index)
288
+
289
+ # if get_index:
290
+ # return [i.atoms for i in self.subgroup_list]
291
+ # else:
292
+ # for l in self.subgroup_list:
293
+ # l.add_smiles(thrsh = star_threshold)
294
+ # return self.subgroup_list
295
+
296
+
297
+ # def get_pattern_list(self, mol):
298
+ # pat_list = []
299
+ # for patt in self.sorted_pattern[1, :]:
300
+ # pat = Chem.MolFromSmarts(patt)
301
+
302
+ # pat_list.append(list(mol.GetSubstructMatches(pat)))
303
+ # return pat_list
304
+
305
+ # def get_masked_pattern_list(self, pat_list, order=4, min_order=-2):
306
+ # upper_layer_mask=np.where(self.sorted_pattern[2]<order+1)[0]
307
+ # lower_ayer_mask=np.where(self.sorted_pattern[2]>=min_order)[0]
308
+ # layer_mask=np.intersect1d(upper_layer_mask,lower_ayer_mask)
309
+ # layer_pat_list = [pat_list[i] for i in layer_mask]
310
+ # layer_sorted_pattern = np.flip(self.sorted_pattern[:,layer_mask],axis=1)
311
+ # return layer_pat_list, layer_sorted_pattern
312
+
313
+ # def init_subgroup_list(self, pat_list, sorted_pattern,log=False,ring_combine=False,mol=None,duplicate_allow=False):
314
+ # used_atom_list=[] # 이미 할당된 원자를 기록
315
+ # subgroup_list=[] # subgroup 객체를 저장할 리스트
316
+ # temporary_ring_list=[]
317
+ # temporary_ring_names=[]
318
+ # for pat_index, groups in enumerate(reversed(pat_list)):
319
+ # if len(groups) and log: print(pat_index,sorted_pattern[0][pat_index],
320
+ # sorted_pattern[1][pat_index],
321
+ # sorted_pattern[2][pat_index],groups)
322
+ # for group in groups:
323
+ # group=list(group)
324
+ # used=False
325
+ # if ring_combine:
326
+ # is_temporary_ring=sorted_pattern[2][pat_index]>=5
327
+
328
+ # if is_temporary_ring:
329
+ # temporary_ring_list.append(group)
330
+ # temporary_ring_names.append(sorted_pattern[0][pat_index])
331
+ # used_atom_list=used_atom_list+group
332
+ # if not duplicate_allow: continue
333
+
334
+ # if not duplicate_allow:
335
+ # for atom_index in group:
336
+ # if atom_index in used_atom_list: used=True
337
+ # if used: continue
338
+
339
+ # used_atom_list=used_atom_list+group
340
+ # subgroup_list.append(Subgroup(self.mol,group,sorted_pattern[0][pat_index],sorted_pattern[2][pat_index]))
341
+ # # subgroup( atoms list, pattern name, priority)
342
+ # if ring_combine:
343
+ # temporary_ring_list2=[]
344
+ # temporary_ring_list2_names=[]
345
+ # for i in range(len(temporary_ring_list)):
346
+ # if temporary_ring_list[i] not in temporary_ring_list2:
347
+ # temporary_ring_list2.append(temporary_ring_list[i])
348
+ # temporary_ring_list2_names.append(temporary_ring_names[i])
349
+
350
+ # if log: print(temporary_ring_list)
351
+ # concated_ring_list, ring_list, concated_names, ring_names =Concat_overlapped(mol,temporary_ring_list2,temporary_ring_list2_names) # 겹치는 고리끼리 합침
352
+ # for concated_ring, concated_name in zip(concated_ring_list,concated_names):
353
+ # subgroup_list.append(Subgroup(self.mol,concated_ring,'poly rings','8'))
354
+ # for ring, ring_name in zip(ring_list,ring_names):
355
+ # subgroup_list.append(Subgroup(self.mol,ring,ring_name,'6'))
356
+
357
+ # for atom_index in range(self.mol_size): # 할당되지 않은 원자에 우선순위 -1 부여
358
+ # if atom_index not in used_atom_list:
359
+ # subgroup_list.append(Subgroup(self.mol,[atom_index],'Undefined','-1'))
360
+
361
+
362
+ # self.subgroup_list = Subgroup_list(self.mol,subgroup_list)
363
+
364
+ # def combine_double_bond_with_ring(self):
365
+ # # 2. 이중결합이 있는 그룹이 고리와 이웃한 경우 합침
366
+ # concat_targets = []
367
+ # for i,subgroup1 in enumerate(self.subgroup_list):
368
+ # if int(subgroup1.priority)>=5:
369
+ # for a in subgroup1.atoms:
370
+ # atom = self.mol.GetAtomWithIdx(int(a))
371
+ # # if not atom.GetIsAromatic(): continue
372
+ # for neighbor in atom.GetNeighbors():
373
+ # neighbor=neighbor.GetIdx()
374
+ # if neighbor in subgroup1.atoms:
375
+ # continue
376
+ # for j,subgroup2 in enumerate(self.subgroup_list):
377
+ # if neighbor in subgroup2.atoms:
378
+ # if len(subgroup2.atoms)!=1: break
379
+ # if self.mol.GetBondBetweenAtoms(int(a),neighbor).GetBondType()==Chem.rdchem.BondType.DOUBLE:
380
+ # concat_targets.append([i,j])
381
+ # break
382
+ # self.subgroup_list.concat(concat_targets,order = '7')
383
+
384
+ # def combine_neighbor_subgroups(self,order=1,log=False):
385
+ # if log:
386
+ # print("combine_neighbor_subgroups")
387
+ # print([(i.name,i.atoms,i.priority) for i in self.subgroup_list])
388
+ # print()
389
+
390
+ # concat_targets=[] # 합칠 대상 검색
391
+
392
+ # for i,subgroup1 in enumerate(self.subgroup_list):
393
+ # if float(subgroup1.priority) < order: # 우선순위가 1보다 작은 그룹을 검색
394
+ # concat_targets.append(i)
395
+ # self.Concat_neighbor_asAll(concat_targets,order) # 검색된 그룹들끼리 이웃하면 합침
396
+
397
+ # def absorb_neighbor_subgroups(self,order=5,log=False):
398
+ # if log:
399
+ # print("absorb_neighbor_subgroups")
400
+ # print([(i.name,i.atoms,i.priority) for i in self.subgroup_list])
401
+ # print()
402
+
403
+ # concat_sbjs=[] # 합칠 주체 검색
404
+ # concat_objs=[] # 합칠 대상 검색
405
+
406
+ # for i,subgroup1 in enumerate(self.subgroup_list):
407
+ # if float(subgroup1.priority) >= order: # 우선순위가 5이상인 큰 그룹을 검색
408
+ # concat_sbjs.append(i)
409
+ # else: # 우선순위가 5보다 작은 그룹을 검색
410
+ # concat_objs.append(i)
411
+ # self.Concat_neighbor_asSubject(concat_sbjs,concat_objs) # 대상이 주체와 이웃하면 합침
412
+
413
+
414
+
415
+ # def Concat_neighbor_asAll(self,frags,order = 1): # frags내의 인접한 frag를 합쳐서 출력
416
+ # concat_targets= []
417
+
418
+ # for i in range(len(frags)):
419
+ # concat_target,concat_targets = self.get_concat_target(frags[i],concat_targets)
420
+ # for j in range(i+1,len(frags)):
421
+ # if self.subgroup_list.is_neighbor(frags[i],frags[j]):
422
+ # concat_target.append(frags[j])
423
+ # concat_targets.append(list(set(concat_target)))
424
+ # self.subgroup_list.concat(concat_targets,order = str(order))
425
+
426
+ # def Concat_neighbor_asSubject(self,sbjs,objs): # sbjs 중심으로 주변의 objs를 합쳐서 출력
427
+ # concat_targets= [[sbj] for sbj in sbjs]
428
+ # used_obj = []
429
+ # for sbj in sbjs.copy():
430
+ # concat_target,concat_targets = self.get_concat_target(sbj,concat_targets)
431
+ # for obj in objs:
432
+ # if self.subgroup_list.is_neighbor(sbj,obj) and obj not in used_obj:
433
+ # concat_target.append(obj)
434
+ # used_obj.append(obj)
435
+ # concat_targets.append(list(set(concat_target)))
436
+ # orders = []
437
+ # for group in concat_targets:
438
+ # max_order = max([int(self.subgroup_list[i].priority) for i in group])
439
+ # orders.append(max_order)
440
+ # self.subgroup_list.concat(concat_targets,order = orders)
441
+
442
+ # @staticmethod
443
+ # def get_concat_target(i,concat_targets):
444
+ # # concat_targets에서 i가 포함된 concat_target을 찾고 concat_targets에서 제거
445
+ # # concat_target이 없으면 i를 포함하는 concat_target을 생성
446
+ # concat_target = None
447
+ # for _target in concat_targets.copy():
448
+ # if i in _target:
449
+ # if concat_target is None:
450
+ # concat_target = _target.copy()
451
+ # else:
452
+ # concat_target = concat_target+_target
453
+ # concat_targets.remove(_target)
454
+ # if concat_target is None:
455
+ # concat_target = [i]
456
+ # return concat_target,concat_targets
457
+
458
+ # class SubgroupSplitter_for_DA(SubgroupSplitter):
459
+ # def __init__(self, refer_path,
460
+ # split_order=6, # 나누기 위한 최대 단위 - 클 수록 더 큰 단위가 우선적으로 고려됨
461
+ # overlapped_ring_combine=False, # 겹치는 고리를 합칠 것인지 여부
462
+ # combine_rest_order=1, # <order> 이하의 그룹은 하나로 묶음, -1이면 묶지 않음
463
+ # absorb_neighbor_order=-1, # <order> 이하의 그룹은 <order> 이상의 그룹에 묶임,
464
+ # # -1이면 묶지 않음
465
+ # log=False,
466
+ # draw=True,
467
+ # get_index=False
468
+ # ):
469
+ # super().__init__(refer_path,split_order,overlapped_ring_combine,combine_rest_order,absorb_neighbor_order,log,draw,get_index)
470
+
471
+ # def fragmentation_with_condition(self,mol,get_index=None):
472
+ # if type(mol)==str: mol = Chem.MolFromSmiles(mol)
473
+ # if get_index is None: get_index=self.get_index
474
+ # self.mol_size = mol.GetNumAtoms()
475
+ # self.mol=mol
476
+ # pat_list = self.get_pattern_list(mol)
477
+
478
+ # # 분자내의 모든 패턴을 찾음
479
+ # layer_pat_list,layer_sorted_pattern = self.get_masked_pattern_list(pat_list,order=self.split_order)
480
+
481
+ # # 찾은 패턴 중 유효한 패턴을 찾음
482
+ # self.init_subgroup_list(layer_pat_list,layer_sorted_pattern,
483
+ # log=self.log,ring_combine=self.overlapped_ring_combine,mol=mol)
484
+
485
+ # # 이웃하는 패턴끼리 합침
486
+ # if self.combine_rest_order>0:
487
+ # self.combine_neighbor_subgroups(order=self.combine_rest_order,log=self.log)
488
+
489
+ # # 1. 카본이 아닌 원자가 두개이상의 그룹과 이웃한 경우 모두 하나로 합침
490
+ # self.combine_notC()
491
+
492
+ # # 3. 두개 이상의 원자로 이루어진 체인이 두개 이상의 그룹과 이웃한 경우 우선순위를 높여서 합쳐지지 않도록 함
493
+ # self.emphasize_bridge()
494
+
495
+ # # 4. 세개 이상의 원자로 이루어진 체인 중 하나의 그룹과 이웃한 경우 aromacity가 있으면 우선순위를 높여서 합쳐지지 않도록 함
496
+ # self.emphasize_conjugated_terminal()
497
+
498
+ # # 5. 링이 한개의 그룹과 이웃한 경우 현재 우선순위가 낮으면 합쳐지도록 함
499
+ # # - 이를 위해 기본 링/가지가 있는 링/폴리사이클링 에 따라 우선순위를 부여함
500
+ # self.neglect_simple_ring()
501
+
502
+
503
+ # # 주변 고리패턴에 흡수됨
504
+ # if self.absorb_neighbor_order>0:
505
+ # self.absorb_neighbor_subgroups(order=self.absorb_neighbor_order,log=self.log)
506
+
507
+ # return self.return_result(self.log,self.draw,get_index)
508
+
509
+ # def combine_notC(self):
510
+ # if self.log:
511
+ # print("combine_notC")
512
+ # print([(i.name,i.atoms,i.priority) for i in self.subgroup_list])
513
+ # print()
514
+ # # 1. 카본이 아닌 원자가 두개이상의 그룹과 이웃한 경우 모두 하나로 합침
515
+ # concat_targets = []
516
+ # adj = self.subgroup_list.adj_mat
517
+ # for i,subgroup1 in enumerate(self.subgroup_list):
518
+ # if len(subgroup1)!=1 or self.mol.GetAtomWithIdx(int(subgroup1.atoms[0])).GetSymbol()=='C' or adj[i,:].sum()==2:
519
+ # continue
520
+ # concat_target,concat_targets = self.get_concat_target(i,concat_targets)
521
+ # for j in range(len(self.subgroup_list)):
522
+ # if i==j: continue
523
+ # if self.subgroup_list.is_neighbor(i,j):
524
+ # concat_target.append(j)
525
+ # concat_targets.append(list(set(concat_target)))
526
+
527
+ # new_concat_targets = []
528
+ # for i in range(len(concat_targets)):
529
+ # if i>=len(concat_targets): break
530
+ # new_target = concat_targets[i].copy()
531
+ # concat_targets.remove(concat_targets[i])
532
+ # count = 0
533
+ # while count<len(concat_targets):
534
+ # c = concat_targets[count]
535
+ # if set.intersection(set(c),set(new_target)):
536
+ # new_target+=c
537
+ # concat_targets.remove(c)
538
+ # count=0
539
+ # continue
540
+ # count+=1
541
+ # new_concat_targets.append(list(set(new_target)))
542
+
543
+ # self.subgroup_list.concat(new_concat_targets,order = '8')
544
+
545
+ # def emphasize_bridge(self):
546
+ # if self.log:
547
+ # print("emphasize_bridge")
548
+ # print([(i.name,i.atoms,i.priority) for i in self.subgroup_list])
549
+ # print()
550
+ # # 3. 두개 이상의 원자로 이루어진 체인이 두개 이상의 그룹과 이웃한 경우 우선순위를 높여서 합쳐지지 않도록 함
551
+ # adj = self.subgroup_list.adj_mat
552
+ # for i,subgroup1 in enumerate(self.subgroup_list):
553
+ # if len(subgroup1)==1: continue
554
+ # if adj[i,:].sum()>=3:
555
+ # subgroup1.priority='7'
556
+
557
+ # def emphasize_conjugated_terminal(self):
558
+ # if self.log:
559
+ # print("emphasize_conjugated_terminal")
560
+ # print([(i.name,i.atoms,i.priority) for i in self.subgroup_list])
561
+ # print()
562
+ # # 4. 세개 이상의 원자로 이루어진 체인 중 하나의 그룹과 이웃한 경우 conjugated되어 있으면 우선순위를 높여서 합쳐지지 않도록 함
563
+ # adj = self.subgroup_list.adj_mat
564
+ # for i,subgroup1 in enumerate(self.subgroup_list):
565
+ # if len(subgroup1)<=2: continue
566
+ # if adj[i,:].sum()!=2: continue
567
+ # count=0
568
+ # for a in subgroup1.atoms:
569
+ # for b in subgroup1.atoms:
570
+ # if a>=b: continue
571
+ # bond = self.mol.GetBondBetweenAtoms(int(a),int(b))
572
+ # if bond and bond.GetIsConjugated():
573
+ # count+=1
574
+ # if count>=3:
575
+ # subgroup1.priority='6'
576
+ # break
577
+
578
+ # def neglect_simple_ring(self):
579
+ # # 5. 링이 한개의 그룹과 이웃한 경우 현재 우선순위가 낮으면 합쳐지도록 함
580
+ # # - 이를 위해 기본 링/가지가 있는 링/폴리사이클링 에 따라 우선순위를 부여함
581
+ # adj = self.subgroup_list.adj_mat
582
+ # target_idx=[]
583
+ # count = 0
584
+ # for i,subgroup1 in enumerate(self.subgroup_list):
585
+ # if int(subgroup1.priority)>=7:
586
+ # count+=1
587
+ # continue
588
+ # if len(subgroup1)>=7: continue
589
+ # if adj[i,:].sum()>2: continue
590
+ # is_simple_ring = True
591
+
592
+ # for a in subgroup1.atoms:
593
+ # if not self.mol.GetAtomWithIdx(int(a)).IsInRing():
594
+ # is_simple_ring=False
595
+ # break
596
+ # if is_simple_ring:
597
+ # target_idx.append(i)
598
+
599
+ # if count<=2:
600
+ # return
601
+ # else:
602
+ # for i in target_idx:
603
+ # self.subgroup_list[i].priority='4'
604
+
605
+
606
+
607
+
608
+
609
+
610
+
611
+
612
+ # def list2int(l):
613
+ # return [int(i) for i in l]
614
+
615
+ # def is_overlapped(mol,frag1,frag2):
616
+ # for atom1 in frag1:
617
+ # if atom1 in frag2: return True
618
+ # return False
619
+
620
+
621
+ # def is_neighbor(mol,frag1,frag2):
622
+ # for atom1 in frag1:
623
+ # for neighbor in mol.GetAtomWithIdx(int(atom1)).GetNeighbors():
624
+ # neighbor=neighbor.GetIdx()
625
+ # if neighbor in frag1: continue
626
+ # if neighbor in frag2: return True
627
+ # return False
628
+
629
+ # def concat_frags(frags):
630
+ # return list(np.concatenate(frags))
631
+
632
+ # def Concat_overlapped(mol, frags, names, _unoverlapped_result=None, _unoverlapped_result_names=None):
633
+ # result = []
634
+ # result_names = []
635
+ # if _unoverlapped_result is None:
636
+ # _unoverlapped_result = frags.copy()
637
+ # _unoverlapped_result_names = names.copy()
638
+ # unoverlapped_result = []
639
+ # unoverlapped_result_names = []
640
+
641
+ # unused_frags=frags.copy()
642
+ # have_concat=False
643
+ # for i, frag1 in enumerate(frags):
644
+ # if not frag1 in unused_frags: continue
645
+ # concat_list=[]
646
+ # name_list = []
647
+ # unused_frags.remove(frag1)
648
+ # used = False
649
+ # for frag2 in frags[i+1:]:
650
+ # if is_overlapped(mol,frag1,frag2) and frag2 in unused_frags:
651
+ # name_list.append(names[frags.index(frag2)])
652
+ # concat_list.append(frag2)
653
+ # unused_frags.remove(frag2)
654
+ # have_concat=True
655
+ # used=True
656
+ # continue
657
+ # if used:
658
+ # concat_list.append(frag1)
659
+ # name_list.append(names[frags.index(frag1)])
660
+ # result_names.append('+'.join(name_list))
661
+ # result.append(concat_frags(concat_list))
662
+ # else:
663
+ # unoverlapped_result.append(frag1)
664
+ # unoverlapped_result_names.append(names[frags.index(frag1)])
665
+
666
+ # new_unoverlapped_result = []
667
+ # new_unoverlapped_result_names = []
668
+ # for u,n in zip(unoverlapped_result,unoverlapped_result_names):
669
+ # if u in _unoverlapped_result:
670
+ # new_unoverlapped_result.append(u)
671
+ # new_unoverlapped_result_names.append(n)
672
+ # else:
673
+ # result.append(u)
674
+ # result_names.append(n)
675
+
676
+ # result= [list(np.unique(i)) for i in result]
677
+ # if have_concat: result,new_unoverlapped_result,result_names,new_unoverlapped_result_names = Concat_overlapped(
678
+ # mol, result+new_unoverlapped_result, result_names+new_unoverlapped_result_names,
679
+ # new_unoverlapped_result, new_unoverlapped_result_names)
680
+ # return result,new_unoverlapped_result,result_names,new_unoverlapped_result_names
681
+
682
+
683
+
684
+
685
+
686
+ # import rdkit
687
+ # import re
688
+ # def get_fragment_with_branch(smi,at_idx):
689
+ # if type(smi)==type(''):
690
+ # mol= Chem.MolFromSmiles(smi)
691
+ # else:
692
+ # mol= smi
693
+ # mol = remove_index_from_mol(mol)
694
+ # smi = Chem.MolToSmiles(mol, allHsExplicit=False, allBondsExplicit=False)
695
+ # mol = Chem.MolFromSmiles(smi)
696
+ # emol=Chem.EditableMol(mol)
697
+ # for i in mol.GetBonds():
698
+ # bond=[i.GetBeginAtomIdx(),i.GetEndAtomIdx()]
699
+ # if len(set.intersection(set(at_idx),set(bond)))==1:
700
+ # r=(bond[0] if bond[0] in at_idx else bond[1])
701
+ # n=emol.AddAtom(Chem.Atom('*'))
702
+ # emol.AddBond(r,n,order=i.GetBondType())
703
+ # emol.RemoveBond(bond[0],bond[1])
704
+ # rs=(Chem.MolToSmiles(emol.GetMol(),kekuleSmiles=False)).split('.')
705
+ # return remove_index(rs[0])
706
+
707
+ # def remove_index(smi):
708
+ # return re.sub(r'\[(.)\1{0,1}H\d?\]',r'\1',smi)
709
+
710
+ # def remove_index_from_mol(mol):
711
+ # for atom in mol.GetAtoms():
712
+ # atom.SetAtomMapNum(0)
713
+ # return mol