1
1
from __future__ import annotations
2
+ from collections .abc import Sequence
2
3
from functools import wraps
3
4
from typing import Union
4
5
from networkx import Graph
@@ -79,7 +80,7 @@ def __init__(self) -> None:
79
80
>>> lg[gcf]
80
81
{spectrum: {"metcalf": Score("metcalf", 1.0, {"cutoff": 0.5})}}
81
82
82
- Get all links:
83
+ Get all links in the LinkGraph :
83
84
>>> lg.links
84
85
[(gcf, spectrum, {"metcalf": Score("metcalf", 1.0, {"cutoff": 0.5})})]
85
86
@@ -129,6 +130,10 @@ def links(
129
130
130
131
Returns:
131
132
A list of tuples containing the links between objects.
133
+
134
+ Examples:
135
+ >>> lg.links
136
+ [(gcf, spectrum, {"metcalf": Score("metcalf", 1.0, {"cutoff": 0.5})})]
132
137
"""
133
138
return list (self ._g .edges (data = True ))
134
139
@@ -150,6 +155,9 @@ def add_link(
150
155
data: keyword arguments. At least one scoring method and its data must be provided.
151
156
The key must be the name of the scoring method defined in `ScoringMethod`, and the
152
157
value is a `Score` object, e.g. `metcalf=Score("metcalf", 1.0, {"cutoff": 0.5})`.
158
+
159
+ Examples:
160
+ >>> lg.add_link(gcf, spectrum, metcalf=Score("metcalf", 1.0, {"cutoff": 0.5}))
153
161
"""
154
162
# validate the data
155
163
if not data :
@@ -174,6 +182,10 @@ def has_link(self, u: Entity, v: Entity) -> bool:
174
182
175
183
Returns:
176
184
True if there is a link between the two objects, False otherwise
185
+
186
+ Examples:
187
+ >>> lg.has_link(gcf, spectrum)
188
+ True
177
189
"""
178
190
return self ._g .has_edge (u , v )
179
191
@@ -192,5 +204,71 @@ def get_link_data(
192
204
Returns:
193
205
A dictionary of scoring methods and their data for the link between the two objects, or
194
206
None if there is no link between the two objects.
207
+
208
+ Examples:
209
+ >>> lg.get_link_data(gcf, spectrum)
210
+ {"metcalf": Score("metcalf", 1.0, {"cutoff": 0.5})}
195
211
"""
196
212
return self ._g .get_edge_data (u , v ) # type: ignore
213
+
214
+ def filter (self , u_nodes : Sequence [Entity ], v_nodes : Sequence [Entity ] = [], / ) -> LinkGraph :
215
+ """Return a new LinkGraph object with the filtered links between the given objects.
216
+
217
+ The new LinkGraph object will only contain the links between `u_nodes` and `v_nodes`.
218
+
219
+ If `u_nodes` or `v_nodes` is empty, the new LinkGraph object will contain the links for
220
+ the given objects in `v_nodes` or `u_nodes`, respectively. If both are empty, return an
221
+ empty LinkGraph object.
222
+
223
+ Note that not all objects in `u_nodes` and `v_nodes` need to be present in the original
224
+ LinkGraph.
225
+
226
+ Args:
227
+ u_nodes: a sequence of objects used as the first object in the links
228
+ v_nodes: a sequence of objects used as the second object in the links
229
+
230
+ Returns:
231
+ A new LinkGraph object with the filtered links between the given objects.
232
+
233
+ Examples:
234
+ Filter the links for `gcf1` and `gcf2`:
235
+ >>> new_lg = lg.filter([gcf1, gcf2])
236
+ Filter the links for `spectrum1` and `spectrum2`:
237
+ >>> new_lg = lg.filter([spectrum1, spectrum2])
238
+ Filter the links between two lists of objects:
239
+ >>> new_lg = lg.filter([gcf1, gcf2], [spectrum1, spectrum2])
240
+ """
241
+ lg = LinkGraph ()
242
+
243
+ # exchange u_nodes and v_nodes if u_nodes is empty but v_nodes not
244
+ if len (u_nodes ) == 0 and len (v_nodes ) != 0 :
245
+ u_nodes = v_nodes
246
+ v_nodes = []
247
+
248
+ if len (v_nodes ) == 0 :
249
+ for u in u_nodes :
250
+ self ._filter_one_node (u , lg )
251
+
252
+ for u in u_nodes :
253
+ for v in v_nodes :
254
+ self ._filter_two_nodes (u , v , lg )
255
+
256
+ return lg
257
+
258
+ @validate_u
259
+ def _filter_one_node (self , u : Entity , lg : LinkGraph ) -> None :
260
+ """Filter the links for a given object and add them to the new LinkGraph object."""
261
+ try :
262
+ links = self [u ]
263
+ except KeyError :
264
+ pass
265
+ else :
266
+ for node2 , value in links .items ():
267
+ lg .add_link (u , node2 , ** value )
268
+
269
+ @validate_uv
270
+ def _filter_two_nodes (self , u : Entity , v : Entity , lg : LinkGraph ) -> None :
271
+ """Filter the links between two objects and add them to the new LinkGraph object."""
272
+ link_data = self .get_link_data (u , v )
273
+ if link_data is not None :
274
+ lg .add_link (u , v , ** link_data )
0 commit comments