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,153 @@
1
+ import torch
2
+ import torch.nn as nn
3
+ import torch.nn.functional as F
4
+ import numpy as np
5
+
6
+ from .GCN import GCN_layer
7
+ from .MPNN import MPNN_layer
8
+ from .distGCN import distGCN_layer
9
+ from .pyg_hetero import relation_graph, relation_sum
10
+
11
+
12
+ def _unbiased_variance_or_zero(values):
13
+ """Preserve unbiased variance except for its undefined one-value case."""
14
+ flattened = values.view(-1)
15
+ if flattened.numel() == 1:
16
+ return flattened.sum() * 0.0
17
+ return torch.var(flattened)
18
+
19
+
20
+ class ISATconvolution(nn.Module):
21
+ def __init__(self, in_node_feats, in_edge_feats, out_feats, activation, n_layers, dropout=0.2, batch_norm=False, residual_sum = False, alpha=0.1, max_dist = 4):
22
+ super().__init__()
23
+ # Message Passing
24
+ self.r2r = nn.ModuleList([MPNN_layer(in_node_feats, in_edge_feats, out_feats, activation, dropout, batch_norm, residual_sum) for _ in range(n_layers)])
25
+ self.i2i = nn.ModuleList([GCN_layer(out_feats, out_feats, activation, dropout, batch_norm, residual_sum) for _ in range(n_layers)])
26
+
27
+ self.r2i = r2i_layer()
28
+ self.i2d = i2s_layer()
29
+ self.d2d = distGCN_layer(out_feats, max_dist, out_feats, activation, alpha)
30
+
31
+ self.d2score = nn.Sequential(nn.Linear(out_feats, out_feats//2),
32
+ nn.LeakyReLU(),
33
+ nn.Linear(out_feats//2, 1)
34
+ )
35
+ self.d2r = s2r_Layer()
36
+ self.batch_norm = nn.BatchNorm1d(1)
37
+
38
+
39
+ def forward(self, graph, r_node, r2r_edge, i_node, d2d_edge):
40
+ real_graph = relation_graph(graph, 'r_nd', 'r2r')
41
+ image_graph = relation_graph(graph, 'i_nd', 'i2i')
42
+ dot_graph = relation_graph(graph, 'd_nd', 'd2d')
43
+
44
+ for i in range(len(self.r2r)):
45
+ r_node = self.r2r[i](real_graph, r_node, r2r_edge)
46
+ i_node = self.r2i(graph, r_node, i_node)
47
+ i_node = self.i2i[i](image_graph, i_node)
48
+ d_node = self.i2d(graph, i_node)
49
+ d_node = self.d2d(dot_graph, d_node, d2d_edge)
50
+ score= self.d2r(graph, d_node)
51
+ score= self.d2score(score)
52
+ score= nn.Sigmoid()(self.batch_norm(score))
53
+
54
+ r_node=score*r_node
55
+ return r_node, score
56
+
57
+ class ISATconvolution_PM(nn.Module):
58
+ def __init__(self, in_node_feats, in_edge_feats, out_feats, activation, n_layers, dropout=0.2, batch_norm=False, residual_sum = False, alpha=0.1, max_dist = 4):
59
+ super().__init__()
60
+ # Message Passing
61
+ self.r2r = nn.ModuleList([MPNN_layer(in_node_feats, in_edge_feats, out_feats, activation, dropout, batch_norm, residual_sum) for _ in range(n_layers)])
62
+
63
+
64
+ self.i2i_P = nn.ModuleList([GCN_layer(out_feats, out_feats, activation, dropout, batch_norm, residual_sum) for _ in range(n_layers)])
65
+ self.d2d_P = distGCN_layer(out_feats, max_dist, out_feats, activation, alpha)
66
+ self.d2score_P = nn.Sequential(nn.Linear(out_feats, out_feats//2),
67
+ nn.LeakyReLU(),
68
+ nn.Linear(out_feats//2, 3),
69
+ nn.LeakyReLU()
70
+ )
71
+ self.d2score_pl = nn.Linear(3, 1)
72
+
73
+ self.i2i_M = nn.ModuleList([GCN_layer(out_feats, out_feats, activation, dropout, batch_norm, residual_sum) for _ in range(n_layers)])
74
+ self.d2d_M = distGCN_layer(out_feats, max_dist, out_feats, activation, alpha)
75
+ self.d2score_M = nn.Sequential(nn.Linear(out_feats, out_feats//2),
76
+ nn.LeakyReLU(),
77
+ nn.Linear(out_feats//2,3),
78
+ nn.LeakyReLU()
79
+ )
80
+ self.d2score_ml = nn.Linear(3, 1)
81
+
82
+ self.r2i = r2i_layer()
83
+ self.i2d = i2s_layer()
84
+ self.d2r = s2r_Layer()
85
+
86
+ self.batch_norm_P = nn.BatchNorm1d(1)
87
+ self.batch_norm_M = nn.BatchNorm1d(1)
88
+
89
+
90
+ def forward(self, graph, r_node, r2r_edge, i_node, d2d_edge, **kargs):
91
+
92
+ real_graph = relation_graph(graph, 'r_nd', 'r2r')
93
+ image_graph = relation_graph(graph, 'i_nd', 'i2i')
94
+ dot_graph = relation_graph(graph, 'd_nd', 'd2d')
95
+
96
+ i_node_P = i_node
97
+ i_node_M = i_node
98
+ for i in range(len(self.r2r)):
99
+ r_node = self.r2r[i](real_graph, r_node, r2r_edge)
100
+
101
+ i_node_P = self.r2i(graph, r_node, i_node_P)
102
+ i_node_P = self.i2i_P[i](image_graph, i_node_P)
103
+
104
+ i_node_M = self.r2i(graph, r_node, i_node_M)
105
+ i_node_M = self.i2i_M[i](image_graph, i_node_M)
106
+
107
+
108
+ d_node_P = self.i2d(graph, i_node_P)
109
+ score_P = self.d2d_P(dot_graph, d_node_P, d2d_edge)
110
+ score_P_temp= score_P.clone()
111
+ score_P= self.d2score_P(score_P)
112
+ score_P= self.d2score_pl(score_P)
113
+ score_P= nn.Sigmoid()(self.batch_norm_P(score_P))
114
+ score_P_node= self.d2r(graph, score_P)
115
+
116
+ r_node_P=score_P_node*r_node
117
+
118
+
119
+ d_node_M = self.i2d(graph, i_node_M)
120
+ score_M = self.d2d_M(dot_graph, d_node_M, d2d_edge)
121
+ score_M_temp= score_M.clone()
122
+ score_M= self.d2score_M(score_M)
123
+ score_M= self.d2score_ml(score_M)
124
+ score_M= nn.Sigmoid()(self.batch_norm_M(score_M))
125
+ score_M_node= self.d2r(graph, score_M)
126
+
127
+ r_node_M=score_M_node*r_node
128
+
129
+ if kargs.get('get_feature',False):
130
+ return score_P_temp, score_M_temp, score_P, score_M # score by group, score by atom
131
+
132
+ self.p_score_var = _unbiased_variance_or_zero(score_P)
133
+ self.n_score_var = _unbiased_variance_or_zero(score_M)
134
+ self.p_score_mean = torch.mean(score_P.view(-1))
135
+ self.n_score_mean = torch.mean(score_M.view(-1))
136
+ self.p_score_ms = torch.mean(torch.square(0.5-score_P.view(-1)))
137
+ self.n_score_ms = torch.mean(torch.square(0.5-score_M.view(-1)))
138
+ return r_node_P, r_node_M, score_P, score_M
139
+
140
+ class r2i_layer(nn.Module):
141
+ def forward(self,graph, r_node, i_node):
142
+ return i_node+r_node
143
+
144
+
145
+ class i2s_layer(nn.Module):
146
+ def forward(self,graph, i_node):
147
+ return relation_sum(graph, 'i_nd', 'i2d', 'd_nd', i_node)
148
+
149
+
150
+ class s2r_Layer(nn.Module):
151
+ def forward(self, graph, node):
152
+ return relation_sum(graph, 'd_nd', 'd2r', 'r_nd', node)
153
+
@@ -0,0 +1,49 @@
1
+ import torch
2
+ import torch.nn as nn
3
+
4
+ class Linears(nn.Module):
5
+ def __init__(self, in_feats, out_feats, activation, n_layers, dropout=0.2, batch_norm=False, residual_sum = False, last= False):
6
+ super().__init__()
7
+ self.activation = activation
8
+ self.dropout = nn.Dropout(dropout)
9
+ self.batch_norm = batch_norm
10
+ self.linears = nn.ModuleList()
11
+ self.batch_norms = nn.ModuleList()
12
+ self.residual_sum = residual_sum
13
+ self.last = last
14
+ hidden_dim = (in_feats+out_feats)//2
15
+ for i in range(n_layers):
16
+ if i==0:
17
+ _in_feats = in_feats
18
+ else:
19
+ _in_feats = hidden_dim
20
+ if i==n_layers-1:
21
+ _out_feats = out_feats
22
+ else:
23
+ _out_feats = hidden_dim
24
+ self.linears.append(nn.Linear(_in_feats, _out_feats))
25
+ if self.batch_norm:
26
+ self.batch_norms.append(nn.BatchNorm1d(_out_feats))
27
+ if residual_sum:
28
+ if in_feats!=out_feats:
29
+ self.residual_layer = nn.Linear(_in_feats, _out_feats)
30
+
31
+ def forward(self, x):
32
+ count=0
33
+ for linear in self.linears:
34
+ count+=1
35
+ h = linear(x)
36
+ if count==len(self.linears) and self.last:
37
+ return h
38
+ else:
39
+ if self.batch_norm:
40
+ h = self.batch_norms[count-1](h)
41
+ h = self.activation(h)
42
+ h = self.dropout(h)
43
+ if self.residual_sum:
44
+ if x.shape[1]==h.shape[1]:
45
+ x = h + x
46
+ else:
47
+ x = h
48
+ return x
49
+
@@ -0,0 +1,56 @@
1
+ import torch.nn as nn
2
+ import torch
3
+
4
+
5
+ class MPNN_layer(nn.Module):
6
+ def __init__(self, in_node_feats, in_edge_feats, out_feats, activation, dropout=0.2, batch_norm=False, residual_sum = False):
7
+ super(MPNN_layer, self).__init__()
8
+ self.activation = activation
9
+ self.dropout = nn.Dropout(dropout)
10
+ self.batch_norm = batch_norm
11
+ self.linear = nn.Linear(in_node_feats*2+in_edge_feats, out_feats)
12
+ self.residual_sum = residual_sum
13
+ if self.batch_norm:
14
+ self.bn = nn.BatchNorm1d(out_feats)
15
+ if residual_sum:
16
+ if in_node_feats!=out_feats:
17
+ self.residual_layer = nn.Linear(in_node_feats, out_feats)
18
+
19
+ def forward(self, graph, node_feats, edge_feats):
20
+ src, dst = graph.edge_index
21
+ messages = self.linear(torch.cat([node_feats[src], node_feats[dst], edge_feats], dim=1))
22
+ h = messages.new_zeros((node_feats.shape[0], messages.shape[1]))
23
+ h.index_add_(0, dst, messages)
24
+ degree = messages.new_zeros((node_feats.shape[0], 1))
25
+ degree.index_add_(0, dst, messages.new_ones((messages.shape[0], 1)))
26
+ h = h / degree.clamp_min(1)
27
+ if self.batch_norm:
28
+ h = self.bn(h)
29
+ h = self.activation(h)
30
+ h = self.dropout(h)
31
+ if self.residual_sum:
32
+ if node_feats.shape[1]!=h.shape[1]:
33
+ node_feats = self.residual_layer(node_feats)
34
+ h = h + node_feats
35
+ return h
36
+
37
+ class MPNNs(nn.Module):
38
+ def __init__(self, in_node_feats, in_edge_feats, hidden_feats, out_feats, activation, n_layers, dropout=0.2, batch_norm=False, residual_sum = False):
39
+ super(MPNNs, self).__init__()
40
+
41
+ self.layers = nn.ModuleList()
42
+ for i in range(n_layers):
43
+ if i==0:
44
+ _in_feats = in_node_feats
45
+ else:
46
+ _in_feats = hidden_feats
47
+ if i==n_layers-1:
48
+ _out_feats = out_feats
49
+ else:
50
+ _out_feats = hidden_feats
51
+ self.layers.append(MPNN_layer(_in_feats, in_edge_feats, _out_feats, activation, dropout, batch_norm, residual_sum))
52
+
53
+ def forward(self, graph, node_feats, edge_feats):
54
+ for layer in self.layers:
55
+ node_feats = layer(graph, node_feats, edge_feats)
56
+ return node_feats
@@ -0,0 +1,62 @@
1
+
2
+ from D4CMPP2.networks.src.GCN import GCNs, graph_sum_pool
3
+ from D4CMPP2.networks.src.Linear import Linears
4
+ import torch.nn as nn
5
+ import torch
6
+
7
+ class SolventLayer(nn.Module):
8
+ def __init__(self, config):
9
+ super(SolventLayer, self).__init__()
10
+
11
+ hidden_dim = config["hidden_dim"]
12
+ linear_layers = config["linear_layers"]
13
+ solvent_hidden_dim = config.get("solvent_hidden_dim", 64)
14
+ solvent_conv_layers = config.get("solvent_conv_layers", 4)
15
+ solvent_linear_layers = config.get("solvent_linear_layers", 2)
16
+ solvent_dropout = config.get("solvent_dropout", 0.2)
17
+ self.node_embedding = nn.Linear(config['node_dim'], hidden_dim)
18
+ self.node_embedding_solv = nn.Linear(
19
+ config["node_dim"], solvent_hidden_dim
20
+ )
21
+
22
+ self.GCNs_solv = GCNs(
23
+ solvent_hidden_dim,
24
+ solvent_hidden_dim,
25
+ solvent_hidden_dim,
26
+ nn.ReLU(),
27
+ solvent_conv_layers,
28
+ solvent_dropout,
29
+ False,
30
+ True,
31
+ )
32
+ self.Linears2 = Linears(
33
+ solvent_hidden_dim,
34
+ solvent_hidden_dim,
35
+ nn.ReLU(),
36
+ solvent_linear_layers,
37
+ solvent_dropout,
38
+ False,
39
+ False,
40
+ )
41
+ self.Linears3 = Linears(
42
+ hidden_dim + solvent_hidden_dim,
43
+ config["target_dim"],
44
+ nn.ReLU(),
45
+ linear_layers,
46
+ config.get("dropout", 0.2),
47
+ False,
48
+ False,
49
+ True,
50
+ )
51
+
52
+ def forward(self, hidden_feats,solv_graph,solv_node_feats,**kwargs):
53
+ h = hidden_feats
54
+
55
+ h_solv = self.node_embedding_solv(solv_node_feats)
56
+ h_solv = self.GCNs_solv(solv_graph, h_solv)
57
+ h_solv = graph_sum_pool(solv_graph, h_solv)
58
+
59
+ h_solv = self.Linears2(h_solv)
60
+ h = torch.cat([h,h_solv],axis=1)
61
+ h = self.Linears3(h)
62
+ return h
File without changes
@@ -0,0 +1,21 @@
1
+ import torch.nn as nn
2
+
3
+
4
+ class distGCN_layer(nn.Module):
5
+ def __init__(self, in_feats, edge_feats, out_feats, activation, alpha=0.1):
6
+ super().__init__()
7
+ self.activation = activation
8
+ self.linear = nn.Linear(in_feats, out_feats)
9
+ self.edge_linear = nn.Linear(edge_feats, out_feats)
10
+ self.alpha = alpha
11
+
12
+ def forward(self, graph, node_feats, edge_feats):
13
+ if len(edge_feats) == 0:
14
+ return node_feats
15
+ src, dst = graph.edge_index
16
+ transformed_nodes = self.linear(node_feats)
17
+ transformed_edges = self.edge_linear(edge_feats)
18
+ messages = transformed_nodes[src] * transformed_edges
19
+ aggregated = messages.new_zeros((node_feats.shape[0], messages.shape[1]))
20
+ aggregated.index_add_(0, dst, messages)
21
+ return node_feats + self.alpha * self.activation(aggregated)
@@ -0,0 +1,24 @@
1
+ from types import SimpleNamespace
2
+
3
+ import torch
4
+
5
+
6
+ def relation_graph(graph, node_type, relation):
7
+ """Expose one homogeneous HeteroData relation to the existing PyG layers."""
8
+ store = graph[node_type]
9
+ batch = getattr(store, 'batch', None)
10
+ if batch is None:
11
+ batch = torch.zeros(store.num_nodes, dtype=torch.long, device=store.x.device)
12
+ return SimpleNamespace(
13
+ edge_index=graph[node_type, relation, node_type].edge_index,
14
+ batch=batch,
15
+ num_graphs=int(getattr(graph, 'num_graphs', 1)),
16
+ )
17
+
18
+
19
+ def relation_sum(graph, source_type, relation, destination_type, source_features):
20
+ """Sum source features at each destination node for one typed relation."""
21
+ src, dst = graph[source_type, relation, destination_type].edge_index
22
+ output = source_features.new_zeros((graph[destination_type].num_nodes, source_features.shape[1]))
23
+ output.index_add_(0, dst, source_features[src])
24
+ return output