risk-network 0.0.3b3__py3-none-any.whl → 0.0.4b0__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.
risk/__init__.py CHANGED
@@ -10,4 +10,4 @@ RISK: RISK Infers Spatial Kinship
10
10
 
11
11
  from risk.risk import RISK
12
12
 
13
- __version__ = "0.0.3-beta.3"
13
+ __version__ = "0.0.4-beta.0"
@@ -171,7 +171,9 @@ def get_description(words_column: pd.Series) -> str:
171
171
  stop_words = set(stopwords.words("english"))
172
172
  # Tokenize the concatenated string and filter out stopwords and non-alphabetic words
173
173
  words = [
174
- word.lower()
174
+ (
175
+ word.lower() if word.istitle() else word
176
+ ) # Lowercase all words except proper nouns (e.g., RNA, mRNA)
175
177
  for word in word_tokenize(words_column.str.cat(sep=" "))
176
178
  if word.isalpha() and word.lower() not in stop_words
177
179
  ]
risk/network/io.py CHANGED
@@ -29,9 +29,6 @@ class NetworkIO:
29
29
  self,
30
30
  compute_sphere: bool = True,
31
31
  surface_depth: float = 0.0,
32
- distance_metric: str = "dijkstra",
33
- edge_length_threshold: float = 0.5,
34
- louvain_resolution: float = 0.1,
35
32
  min_edges_per_node: int = 0,
36
33
  include_edge_weight: bool = True,
37
34
  weight_label: str = "weight",
@@ -40,9 +37,6 @@ class NetworkIO:
40
37
  self.surface_depth = surface_depth
41
38
  self.include_edge_weight = include_edge_weight
42
39
  self.weight_label = weight_label
43
- self.distance_metric = distance_metric
44
- self.edge_length_threshold = edge_length_threshold
45
- self.louvain_resolution = louvain_resolution
46
40
  self.min_edges_per_node = min_edges_per_node
47
41
 
48
42
  def load_gpickle_network(self, filepath: str) -> nx.Graph:
@@ -320,7 +314,6 @@ class NetworkIO:
320
314
  print(f"Projection: {'Sphere' if self.compute_sphere else 'Plane'}")
321
315
  if self.compute_sphere:
322
316
  print(f"Surface depth: {self.surface_depth}")
323
- print(f"Edge length threshold: {self.edge_length_threshold}")
324
317
  print(f"Edge weight: {'Included' if self.include_edge_weight else 'Excluded'}")
325
318
  if self.include_edge_weight:
326
319
  print(f"Weight label: {self.weight_label}")
risk/network/plot.py CHANGED
@@ -299,11 +299,11 @@ class NetworkPlotter:
299
299
  """
300
300
  # Log the plotting parameters
301
301
  params.log_plotter(
302
- contour_levels=levels,
303
- contour_bandwidth=bandwidth,
304
- contour_grid_size=grid_size,
305
- contour_alpha=alpha,
306
- contour_color="custom" if isinstance(color, np.ndarray) else color,
302
+ subcontour_levels=levels,
303
+ subcontour_bandwidth=bandwidth,
304
+ subcontour_grid_size=grid_size,
305
+ subcontour_alpha=alpha,
306
+ subcontour_color="custom" if isinstance(color, np.ndarray) else color,
307
307
  )
308
308
  # Filter to get node IDs and their coordinates
309
309
  node_ids = [
@@ -402,7 +402,7 @@ class NetworkPlotter:
402
402
  fontcolor: Union[str, np.ndarray] = "black",
403
403
  arrow_linewidth: float = 1,
404
404
  arrow_color: Union[str, np.ndarray] = "black",
405
- num_words: int = 10,
405
+ max_words: int = 10,
406
406
  min_words: int = 1,
407
407
  ) -> None:
408
408
  """Annotate the network graph with labels for different domains, positioned around the network for clarity.
@@ -415,7 +415,7 @@ class NetworkPlotter:
415
415
  fontcolor (str or np.ndarray, optional): Color of the label text. Can be a string or RGBA array. Defaults to "black".
416
416
  arrow_linewidth (float, optional): Line width of the arrows pointing to centroids. Defaults to 1.
417
417
  arrow_color (str or np.ndarray, optional): Color of the arrows. Can be a string or RGBA array. Defaults to "black".
418
- num_words (int, optional): Maximum number of words in a label. Defaults to 10.
418
+ max_words (int, optional): Maximum number of words in a label. Defaults to 10.
419
419
  min_words (int, optional): Minimum number of words required to display a label. Defaults to 1.
420
420
  """
421
421
  # Log the plotting parameters
@@ -427,7 +427,7 @@ class NetworkPlotter:
427
427
  label_fontcolor="custom" if isinstance(fontcolor, np.ndarray) else fontcolor,
428
428
  label_arrow_linewidth=arrow_linewidth,
429
429
  label_arrow_color="custom" if isinstance(arrow_color, np.ndarray) else arrow_color,
430
- label_num_words=num_words,
430
+ label_max_words=max_words,
431
431
  label_min_words=min_words,
432
432
  )
433
433
  # Convert color strings to RGBA arrays if necessary
@@ -442,24 +442,37 @@ class NetworkPlotter:
442
442
  if nodes: # Skip if the domain has no nodes
443
443
  domain_centroids[domain] = self._calculate_domain_centroid(nodes)
444
444
 
445
+ # Initialize empty lists to collect valid indices
446
+ valid_indices = []
447
+ filtered_domain_centroids = {}
448
+ # Loop through domain_centroids with index
449
+ for idx, (domain, centroid) in enumerate(domain_centroids.items()):
450
+ # Check if the domain passes the word count condition
451
+ if (
452
+ len(self.network_graph.trimmed_domain_to_term[domain].split(" ")[:max_words])
453
+ >= min_words
454
+ ):
455
+ # Add to filtered_domain_centroids
456
+ filtered_domain_centroids[domain] = centroid
457
+ # Keep track of the valid index
458
+ valid_indices.append(idx)
459
+
460
+ # Now filter fontcolor and arrow_color to keep only the valid indices
461
+ fontcolor = fontcolor[valid_indices]
462
+ arrow_color = arrow_color[valid_indices]
463
+
445
464
  # Calculate the bounding box around the network
446
465
  center, radius = _calculate_bounding_box(
447
466
  self.network_graph.node_coordinates, radius_margin=perimeter_scale
448
467
  )
449
-
450
- # Filter out domains with insufficient words for labeling
451
- filtered_domains = {
452
- domain: centroid
453
- for domain, centroid in domain_centroids.items()
454
- if len(self.network_graph.trimmed_domain_to_term[domain].split(" ")[:num_words])
455
- >= min_words
456
- }
457
468
  # Calculate the best positions for labels around the perimeter
458
- best_label_positions = _best_label_positions(filtered_domains, center, radius, offset)
469
+ best_label_positions = _best_label_positions(
470
+ filtered_domain_centroids, center, radius, offset
471
+ )
459
472
  # Annotate the network with labels
460
473
  for idx, (domain, pos) in enumerate(best_label_positions.items()):
461
- centroid = filtered_domains[domain]
462
- annotations = self.network_graph.trimmed_domain_to_term[domain].split(" ")[:num_words]
474
+ centroid = filtered_domain_centroids[domain]
475
+ annotations = self.network_graph.trimmed_domain_to_term[domain].split(" ")[:max_words]
463
476
  self.ax.annotate(
464
477
  "\n".join(annotations),
465
478
  xy=centroid,
@@ -473,6 +486,81 @@ class NetworkPlotter:
473
486
  arrowprops=dict(arrowstyle="->", color=arrow_color[idx], linewidth=arrow_linewidth),
474
487
  )
475
488
 
489
+ def plot_sublabel(
490
+ self,
491
+ nodes: list,
492
+ label: str,
493
+ radial_position: float = 0.0,
494
+ perimeter_scale: float = 1.05,
495
+ offset: float = 0.10,
496
+ font: str = "Arial",
497
+ fontsize: int = 10,
498
+ fontcolor: str = "black",
499
+ arrow_linewidth: float = 1,
500
+ arrow_color: str = "black",
501
+ ) -> None:
502
+ """Annotate the network graph with a single label for the given nodes, positioned at a specified radial angle.
503
+
504
+ Args:
505
+ nodes (List[str]): List of node labels to be used for calculating the centroid.
506
+ label (str): The label to be annotated on the network.
507
+ radial_position (float, optional): Radial angle for positioning the label, in degrees (0-360). Defaults to 0.0.
508
+ perimeter_scale (float, optional): Scale factor for positioning the label around the perimeter. Defaults to 1.05.
509
+ offset (float, optional): Offset distance for the label from the perimeter. Defaults to 0.10.
510
+ font (str, optional): Font name for the label. Defaults to "Arial".
511
+ fontsize (int, optional): Font size for the label. Defaults to 10.
512
+ fontcolor (str, optional): Color of the label text. Defaults to "black".
513
+ arrow_linewidth (float, optional): Line width of the arrow pointing to the centroid. Defaults to 1.
514
+ arrow_color (str, optional): Color of the arrow. Defaults to "black".
515
+ """
516
+ # Log the plotting parameters
517
+ params.log_plotter(
518
+ sublabel_perimeter_scale=perimeter_scale,
519
+ sublabel_offset=offset,
520
+ sublabel_font=font,
521
+ sublabel_fontsize=fontsize,
522
+ sublabel_fontcolor="custom" if isinstance(fontcolor, np.ndarray) else fontcolor,
523
+ sublabel_arrow_linewidth=arrow_linewidth,
524
+ sublabel_arrow_color="custom" if isinstance(arrow_color, np.ndarray) else arrow_color,
525
+ sublabel_radial_position=radial_position,
526
+ )
527
+
528
+ # Map node labels to IDs
529
+ node_ids = [
530
+ self.network_graph.node_label_to_id_map.get(node)
531
+ for node in nodes
532
+ if node in self.network_graph.node_label_to_id_map
533
+ ]
534
+
535
+ # Calculate the centroid of the provided nodes
536
+ centroid = self._calculate_domain_centroid(node_ids)
537
+
538
+ # Calculate the bounding box around the network
539
+ center, radius = _calculate_bounding_box(
540
+ self.network_graph.node_coordinates, radius_margin=perimeter_scale
541
+ )
542
+
543
+ # Convert radial position to radians, adjusting for a 90-degree rotation
544
+ radial_radians = np.deg2rad(radial_position - 90)
545
+ label_position = (
546
+ center[0] + (radius + offset) * np.cos(radial_radians),
547
+ center[1] + (radius + offset) * np.sin(radial_radians),
548
+ )
549
+
550
+ # Annotate the network with the label
551
+ self.ax.annotate(
552
+ label,
553
+ xy=centroid,
554
+ xytext=label_position,
555
+ textcoords="data",
556
+ ha="center",
557
+ va="center",
558
+ fontsize=fontsize,
559
+ fontname=font,
560
+ color=fontcolor,
561
+ arrowprops=dict(arrowstyle="->", color=arrow_color, linewidth=arrow_linewidth),
562
+ )
563
+
476
564
  def _calculate_domain_centroid(self, nodes: list) -> tuple:
477
565
  """Calculate the most centrally located node in .
478
566
 
@@ -662,12 +750,12 @@ def _calculate_bounding_box(
662
750
 
663
751
 
664
752
  def _best_label_positions(
665
- filtered_domains: Dict[str, Any], center: np.ndarray, radius: float, offset: float
753
+ filtered_domain_centroids: Dict[str, Any], center: np.ndarray, radius: float, offset: float
666
754
  ) -> Dict[str, Any]:
667
755
  """Calculate and optimize label positions for clarity.
668
756
 
669
757
  Args:
670
- filtered_domains (dict): Centroids of the filtered domains.
758
+ filtered_domain_centroids (dict): Centroids of the filtered domains.
671
759
  center (np.ndarray): The center coordinates for label positioning.
672
760
  radius (float): The radius for positioning labels around the center.
673
761
  offset (float): The offset distance from the radius for positioning labels.
@@ -675,15 +763,16 @@ def _best_label_positions(
675
763
  Returns:
676
764
  dict: Optimized positions for labels.
677
765
  """
678
- num_domains = len(filtered_domains)
766
+ num_domains = len(filtered_domain_centroids)
679
767
  # Calculate equidistant positions around the center for initial label placement
680
768
  equidistant_positions = _equidistant_angles_around_center(center, radius, offset, num_domains)
681
769
  # Create a mapping of domains to their initial label positions
682
770
  label_positions = {
683
- domain: position for domain, position in zip(filtered_domains.keys(), equidistant_positions)
771
+ domain: position
772
+ for domain, position in zip(filtered_domain_centroids.keys(), equidistant_positions)
684
773
  }
685
774
  # Optimize the label positions to minimize distance to domain centroids
686
- return _optimize_label_positions(label_positions, filtered_domains)
775
+ return _optimize_label_positions(label_positions, filtered_domain_centroids)
687
776
 
688
777
 
689
778
  def _equidistant_angles_around_center(
risk/risk.py CHANGED
@@ -31,10 +31,7 @@ class RISK(NetworkIO, AnnotationsIO):
31
31
  self,
32
32
  compute_sphere: bool = True,
33
33
  surface_depth: float = 0.0,
34
- distance_metric: str = "dijkstra",
35
- louvain_resolution: float = 0.1,
36
34
  min_edges_per_node: int = 0,
37
- edge_length_threshold: float = 0.5,
38
35
  include_edge_weight: bool = True,
39
36
  weight_label: str = "weight",
40
37
  ):
@@ -43,10 +40,7 @@ class RISK(NetworkIO, AnnotationsIO):
43
40
  Args:
44
41
  compute_sphere (bool, optional): Whether to map nodes to a sphere. Defaults to True.
45
42
  surface_depth (float, optional): Surface depth for the sphere. Defaults to 0.0.
46
- distance_metric (str, optional): Distance metric to use in network analysis. Defaults to "dijkstra".
47
- louvain_resolution (float, optional): Resolution parameter for Louvain clustering. Defaults to 0.1.
48
43
  min_edges_per_node (int, optional): Minimum number of edges per node. Defaults to 0.
49
- edge_length_threshold (float, optional): Edge length threshold for analysis. Defaults to 0.5.
50
44
  include_edge_weight (bool, optional): Whether to include edge weights in calculations. Defaults to True.
51
45
  weight_label (str, optional): Label for edge weights. Defaults to "weight".
52
46
  """
@@ -55,10 +49,7 @@ class RISK(NetworkIO, AnnotationsIO):
55
49
  params.log_network(
56
50
  compute_sphere=compute_sphere,
57
51
  surface_depth=surface_depth,
58
- distance_metric=distance_metric,
59
- louvain_resolution=louvain_resolution,
60
52
  min_edges_per_node=min_edges_per_node,
61
- edge_length_threshold=edge_length_threshold,
62
53
  include_edge_weight=include_edge_weight,
63
54
  weight_label=weight_label,
64
55
  )
@@ -67,10 +58,7 @@ class RISK(NetworkIO, AnnotationsIO):
67
58
  self,
68
59
  compute_sphere=compute_sphere,
69
60
  surface_depth=surface_depth,
70
- distance_metric=distance_metric,
71
- louvain_resolution=louvain_resolution,
72
61
  min_edges_per_node=min_edges_per_node,
73
- edge_length_threshold=edge_length_threshold,
74
62
  include_edge_weight=include_edge_weight,
75
63
  weight_label=weight_label,
76
64
  )
@@ -79,10 +67,7 @@ class RISK(NetworkIO, AnnotationsIO):
79
67
  # Set class attributes
80
68
  self.compute_sphere = compute_sphere
81
69
  self.surface_depth = surface_depth
82
- self.distance_metric = distance_metric
83
- self.louvain_resolution = louvain_resolution
84
70
  self.min_edges_per_node = min_edges_per_node
85
- self.edge_length_threshold = edge_length_threshold
86
71
  self.include_edge_weight = include_edge_weight
87
72
  self.weight_label = weight_label
88
73
 
@@ -95,6 +80,9 @@ class RISK(NetworkIO, AnnotationsIO):
95
80
  self,
96
81
  network: nx.Graph,
97
82
  annotations: Dict[str, Any],
83
+ distance_metric: str = "dijkstra",
84
+ louvain_resolution: float = 0.1,
85
+ edge_length_threshold: float = 0.5,
98
86
  score_metric: str = "sum",
99
87
  null_distribution: str = "network",
100
88
  num_permutations: int = 1000,
@@ -106,6 +94,9 @@ class RISK(NetworkIO, AnnotationsIO):
106
94
  Args:
107
95
  network (nx.Graph): The network graph.
108
96
  annotations (pd.DataFrame): The matrix of annotations associated with the network.
97
+ distance_metric (str, optional): Distance metric for neighborhood analysis. Defaults to "dijkstra".
98
+ louvain_resolution (float, optional): Resolution parameter for Louvain clustering. Defaults to 0.1.
99
+ edge_length_threshold (float, optional): Edge length threshold for neighborhood analysis. Defaults to 0.5.
109
100
  score_metric (str, optional): Scoring metric for neighborhood significance. Defaults to "sum".
110
101
  null_distribution (str, optional): Distribution used for permutation tests. Defaults to "network".
111
102
  num_permutations (int, optional): Number of permutations for significance testing. Defaults to 1000.
@@ -118,6 +109,9 @@ class RISK(NetworkIO, AnnotationsIO):
118
109
  print_header("Running permutation test")
119
110
  # Log neighborhood analysis parameters
120
111
  params.log_neighborhoods(
112
+ distance_metric=distance_metric,
113
+ louvain_resolution=louvain_resolution,
114
+ edge_length_threshold=edge_length_threshold,
121
115
  score_metric=score_metric,
122
116
  null_distribution=null_distribution,
123
117
  num_permutations=num_permutations,
@@ -126,17 +120,18 @@ class RISK(NetworkIO, AnnotationsIO):
126
120
  )
127
121
 
128
122
  # Display the chosen distance metric
129
- if self.distance_metric == "louvain":
130
- for_print_distance_metric = f"louvain (resolution={self.louvain_resolution})"
123
+ if distance_metric == "louvain":
124
+ for_print_distance_metric = f"louvain (resolution={louvain_resolution})"
131
125
  else:
132
- for_print_distance_metric = self.distance_metric
126
+ for_print_distance_metric = distance_metric
133
127
  print(f"Distance metric: '{for_print_distance_metric}'")
128
+ print(f"Edge length threshold: {edge_length_threshold}")
134
129
  # Compute neighborhoods based on the network and distance metric
135
130
  neighborhoods = get_network_neighborhoods(
136
131
  network,
137
- self.distance_metric,
138
- self.edge_length_threshold,
139
- louvain_resolution=self.louvain_resolution,
132
+ distance_metric,
133
+ edge_length_threshold,
134
+ louvain_resolution=louvain_resolution,
140
135
  random_seed=random_seed,
141
136
  )
142
137
 
@@ -144,6 +139,8 @@ class RISK(NetworkIO, AnnotationsIO):
144
139
  print(f"Null distribution: '{null_distribution}'")
145
140
  print(f"Neighborhood scoring metric: '{score_metric}'")
146
141
  print(f"Number of permutations: {num_permutations}")
142
+ print(f"Random seed: {random_seed}")
143
+ print(f"Maximum workers: {max_workers}")
147
144
  # Run the permutation test to compute neighborhood significance
148
145
  neighborhood_significance = compute_permutation(
149
146
  neighborhoods=neighborhoods,
risk/stats/stats.py CHANGED
@@ -150,12 +150,14 @@ def _run_permutation_test(
150
150
  ]
151
151
 
152
152
  # Start the permutation process in parallel
153
- results = pool.starmap_async(_permutation_process_subset, params_list)
153
+ results = pool.starmap_async(_permutation_process_subset, params_list, chunksize=1)
154
154
 
155
155
  # Update progress bar based on progress_counter
156
+ # NOTE: Waiting for results to be ready while updating progress bar gives a big improvement
157
+ # in performance, especially for large number of permutations and workers
156
158
  while not results.ready():
157
159
  progress.update(progress_counter.value - progress.n)
158
- results.wait(0.1)
160
+ results.wait(0.05) # Wait for 50ms
159
161
 
160
162
  # Ensure progress bar reaches 100%
161
163
  progress.update(total_progress - progress.n)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: risk-network
3
- Version: 0.0.3b3
3
+ Version: 0.0.4b0
4
4
  Summary: A Python package for biological network analysis
5
5
  Author: Ira Horecka
6
6
  Author-email: Ira Horecka <ira89@icloud.com>
@@ -736,7 +736,7 @@ RISK is a software tool for visualizing spatial relationships in networks. It ai
736
736
 
737
737
  *Saccharomyces cerevisiae* proteins oriented by physical interactions discovered through affinity enrichment and mass spectrometry (Michaelis et al., 2023).
738
738
 
739
- ![Metabolic Network Demo](./docs/github/network.png)
739
+ ![PPI Network Demo](./docs/github/network.png)
740
740
 
741
741
  ## Installation
742
742
 
@@ -1,8 +1,8 @@
1
- risk/__init__.py,sha256=RJu5X2UMuCRnZae_KH4Fc7_o_P4sSfTDEBowiVZ2Go4,122
1
+ risk/__init__.py,sha256=_RCFU6OMr2y2rQgkEL8v7GNdoRzp66xcSTHGsIJYDuU,122
2
2
  risk/constants.py,sha256=AICk3x5qRQhls_ijTb4VdbdxU6mZ1aLGbAjLEdBwfJI,550
3
- risk/risk.py,sha256=cWpYogZ-vma4ZZjewVNRMzb2TqHv8YABuzP2brXpOqo,16399
3
+ risk/risk.py,sha256=GSIhjtn__c6752O9fSLCHH21mY0m8XDKIiLLaDmPhoI,16228
4
4
  risk/annotations/__init__.py,sha256=vUpVvMRE5if01Ic8QY6M2Ae3EFGJHdugEe9PdEkAW4Y,138
5
- risk/annotations/annotations.py,sha256=gZ9gihK_eTWaX3eByh08xr97FX4-XKe6MBwCCjasEDU,10368
5
+ risk/annotations/annotations.py,sha256=0-Yf2XPVdMzpttLLgLxtTTnH0Eed_Uv8VXMur6E6xKw,10481
6
6
  risk/annotations/io.py,sha256=ozi7aFn3_geB6G0kt7Ya1qVhNOqP6rB0YISjriSZyNw,7989
7
7
  risk/log/__init__.py,sha256=xuLImfxFlKpnVhzi_gDYlr2_c9cLkrw2c_3iEsXb1as,107
8
8
  risk/log/console.py,sha256=im9DRExwf6wHlcn9fewoDcKIpo3vPcorZIaNAl-0csY,355
@@ -14,13 +14,13 @@ risk/neighborhoods/neighborhoods.py,sha256=zGtxVIs0_Bg0wt1By6d77_lqW0PGXpOtQxeCE
14
14
  risk/network/__init__.py,sha256=iEPeJdZfqp0toxtbElryB8jbz9_t_k4QQ3iDvKE8C_0,126
15
15
  risk/network/geometry.py,sha256=euBMOVvxpj-0WZam40IbHdsT7E4WXpTwSxuGbmAGTDg,6757
16
16
  risk/network/graph.py,sha256=a7gM1d2jHqscFVwn1GZaJWb3oZOFraNsQ2RxC4osaV4,11528
17
- risk/network/io.py,sha256=KmdrsDZe-ZT4O59NYZM_nQd8Ew9qpbzQcqWS_PaE7eA,12559
18
- risk/network/plot.py,sha256=fy21X677xqJPFkn564Jegxy05C9x0pJXovd5fm3NZ4Q,34554
17
+ risk/network/io.py,sha256=KR838qmbDjUX0ziXJ15pgT6LgdKRf3zJpxxAv0VtzbM,12202
18
+ risk/network/plot.py,sha256=dbACRp73EnZZwdOAoIiMivhDn-b1MSDOxUcgSFRHOLI,38465
19
19
  risk/stats/__init__.py,sha256=4s9gdJo5B1G_cQc0iMoeIBt5OrQNXkdtNXkAMFQkLxc,103
20
20
  risk/stats/permutation.py,sha256=xgaZbaxo57t_FzPlpcb2nsq8oCzc_wj-zAm-xj3P2dA,3404
21
- risk/stats/stats.py,sha256=_3Fj5H8Nml4cExvLg7Mt_i1HCLAJJcJSDiiSzr3uFlo,15798
22
- risk_network-0.0.3b3.dist-info/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
23
- risk_network-0.0.3b3.dist-info/METADATA,sha256=4zGYMG1NL48Udn8jYkT8VCYDEEAuN5ycXBpvmxvdHtw,43256
24
- risk_network-0.0.3b3.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
25
- risk_network-0.0.3b3.dist-info/top_level.txt,sha256=NX7C2PFKTvC1JhVKv14DFlFAIFnKc6Lpsu1ZfxvQwVw,5
26
- risk_network-0.0.3b3.dist-info/RECORD,,
21
+ risk/stats/stats.py,sha256=7Z-1sJ5zvS3XDjG2UfOV0Y3c3xliYeB-6fk_UHNqfiE,16019
22
+ risk_network-0.0.4b0.dist-info/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
23
+ risk_network-0.0.4b0.dist-info/METADATA,sha256=UgNIQbca_cOb1Ft3kBJ0qil5sF2Y392uzS1HDKfLqUU,43250
24
+ risk_network-0.0.4b0.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
25
+ risk_network-0.0.4b0.dist-info/top_level.txt,sha256=NX7C2PFKTvC1JhVKv14DFlFAIFnKc6Lpsu1ZfxvQwVw,5
26
+ risk_network-0.0.4b0.dist-info/RECORD,,