nettracer3d 1.2.7__py3-none-any.whl → 1.3.6__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.
Potentially problematic release.
This version of nettracer3d might be problematic. Click here for more details.
- nettracer3d/branch_stitcher.py +245 -142
- nettracer3d/community_extractor.py +3 -2
- nettracer3d/endpoint_joiner.py +286 -0
- nettracer3d/filaments.py +348 -106
- nettracer3d/histos.py +1182 -0
- nettracer3d/modularity.py +14 -96
- nettracer3d/neighborhoods.py +3 -2
- nettracer3d/nettracer.py +296 -82
- nettracer3d/nettracer_gui.py +2275 -2770
- nettracer3d/network_analysis.py +28 -9
- nettracer3d/network_graph_widget.py +2267 -0
- nettracer3d/painting.py +158 -298
- nettracer3d/segmenter.py +1 -1
- nettracer3d/segmenter_GPU.py +0 -1
- nettracer3d/simple_network.py +4 -4
- nettracer3d/smart_dilate.py +19 -7
- nettracer3d/tutorial.py +77 -26
- {nettracer3d-1.2.7.dist-info → nettracer3d-1.3.6.dist-info}/METADATA +50 -18
- nettracer3d-1.3.6.dist-info/RECORD +32 -0
- {nettracer3d-1.2.7.dist-info → nettracer3d-1.3.6.dist-info}/WHEEL +1 -1
- nettracer3d-1.2.7.dist-info/RECORD +0 -29
- {nettracer3d-1.2.7.dist-info → nettracer3d-1.3.6.dist-info}/entry_points.txt +0 -0
- {nettracer3d-1.2.7.dist-info → nettracer3d-1.3.6.dist-info}/licenses/LICENSE +0 -0
- {nettracer3d-1.2.7.dist-info → nettracer3d-1.3.6.dist-info}/top_level.txt +0 -0
nettracer3d/simple_network.py
CHANGED
|
@@ -222,13 +222,13 @@ def show_identity_network(excel_file_path, node_identities, geometric=False, geo
|
|
|
222
222
|
# Node size handling
|
|
223
223
|
node_dict = {}
|
|
224
224
|
for node in G.nodes():
|
|
225
|
-
try:
|
|
225
|
+
try: #Perhaps remove this
|
|
226
226
|
if identity_dict[node] == 'Edge':
|
|
227
|
-
node_dict[node] =
|
|
227
|
+
node_dict[node] = 10
|
|
228
228
|
else:
|
|
229
|
-
node_dict[node] =
|
|
229
|
+
node_dict[node] = 10
|
|
230
230
|
except:
|
|
231
|
-
node_dict[node] =
|
|
231
|
+
node_dict[node] = 10
|
|
232
232
|
|
|
233
233
|
if geometric:
|
|
234
234
|
# Handle geometric positioning
|
nettracer3d/smart_dilate.py
CHANGED
|
@@ -7,7 +7,11 @@ from concurrent.futures import ThreadPoolExecutor, as_completed, ProcessPoolExec
|
|
|
7
7
|
from skimage.segmentation import watershed
|
|
8
8
|
import cv2
|
|
9
9
|
import os
|
|
10
|
-
|
|
10
|
+
try:
|
|
11
|
+
import edt
|
|
12
|
+
print("Parallel search functions enabled")
|
|
13
|
+
except:
|
|
14
|
+
print("Some parallel search functions disabled (requires edt package), will fall back to single-threaded")
|
|
11
15
|
import math
|
|
12
16
|
import re
|
|
13
17
|
from . import nettracer
|
|
@@ -293,9 +297,13 @@ def process_chunk(start_idx, end_idx, nodes, ring_mask, nearest_label_indices):
|
|
|
293
297
|
def smart_dilate(nodes, dilate_xy = 0, dilate_z = 0, directory = None, GPU = True, fast_dil = True, predownsample = None, use_dt_dil_amount = None, xy_scale = 1, z_scale = 1):
|
|
294
298
|
|
|
295
299
|
if fast_dil:
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
300
|
+
try:
|
|
301
|
+
import edt
|
|
302
|
+
dilated = nettracer.dilate_3D_dt(nodes, use_dt_dil_amount, xy_scale, z_scale, fast_dil = True)
|
|
303
|
+
return smart_label_watershed(dilated, nodes, directory = None, remove_template = False)
|
|
304
|
+
except:
|
|
305
|
+
print("edt package not found. Please use 'pip install edt' if you would like to enable parallel searching.")
|
|
306
|
+
return smart_dilate_short(nodes, use_dt_dil_amount, directory, xy_scale, z_scale)
|
|
299
307
|
else:
|
|
300
308
|
return smart_dilate_short(nodes, use_dt_dil_amount, directory, xy_scale, z_scale)
|
|
301
309
|
|
|
@@ -699,7 +707,7 @@ def compute_distance_transform_distance(nodes, sampling=[1, 1, 1], fast_dil=Fals
|
|
|
699
707
|
str(nodes.dtype),
|
|
700
708
|
tuple(sampling)
|
|
701
709
|
)
|
|
702
|
-
result_shape, result_dtype = future.result(
|
|
710
|
+
result_shape, result_dtype = future.result()
|
|
703
711
|
|
|
704
712
|
distance = np.ndarray(result_shape, dtype=result_dtype, buffer=output_shm.buf).copy()
|
|
705
713
|
|
|
@@ -711,8 +719,12 @@ def compute_distance_transform_distance(nodes, sampling=[1, 1, 1], fast_dil=Fals
|
|
|
711
719
|
|
|
712
720
|
except Exception as e:
|
|
713
721
|
print(f"Parallel distance transform failed ({e}), falling back to scipy")
|
|
714
|
-
|
|
715
|
-
|
|
722
|
+
try:
|
|
723
|
+
import edt
|
|
724
|
+
import traceback
|
|
725
|
+
traceback.print_exc() # See the full error
|
|
726
|
+
except:
|
|
727
|
+
print("edt package not found. Please use 'pip install edt' if you would like to enable parallel searching.")
|
|
716
728
|
distance = distance_transform_edt(nodes, sampling=sampling)
|
|
717
729
|
else:
|
|
718
730
|
distance = distance_transform_edt(nodes, sampling=sampling)
|
nettracer3d/tutorial.py
CHANGED
|
@@ -879,28 +879,28 @@ def setup_start_tutorial(window):
|
|
|
879
879
|
|
|
880
880
|
# Step 1: Welcome
|
|
881
881
|
tutorial.add_step(
|
|
882
|
-
window.
|
|
882
|
+
window.graphics_widget,
|
|
883
883
|
"Welcome to NetTracer3D! This tutorial will give you a basic overview of this application. Click 'Next' or use Right-Click to continue.",
|
|
884
884
|
highlight_type=None,
|
|
885
885
|
message_position="bottom"
|
|
886
886
|
)
|
|
887
887
|
|
|
888
888
|
tutorial.add_step(
|
|
889
|
-
window.
|
|
889
|
+
window.graphics_widget,
|
|
890
890
|
"This program is designed to analysis of two or three dimensional images, such as those aquired via microscopy or medical imaging.",
|
|
891
891
|
highlight_type=None,
|
|
892
892
|
message_position="bottom"
|
|
893
893
|
)
|
|
894
894
|
|
|
895
895
|
tutorial.add_step(
|
|
896
|
-
window.
|
|
896
|
+
window.graphics_widget,
|
|
897
897
|
"The major form of analysis is done by creating undirected networks between objects of interest, called nodes. These can be biological structures such as cells or functional tissue units.",
|
|
898
898
|
highlight_type=None,
|
|
899
899
|
message_position="bottom"
|
|
900
900
|
)
|
|
901
901
|
|
|
902
902
|
tutorial.add_step(
|
|
903
|
-
window.
|
|
903
|
+
window.graphics_widget,
|
|
904
904
|
"Analysis can also be done on more direct measures of morphology or spatial arrangement, such as analyzing object measures like volumes or making clustering heatmaps.",
|
|
905
905
|
highlight_type=None,
|
|
906
906
|
message_position="bottom"
|
|
@@ -915,14 +915,14 @@ def setup_start_tutorial(window):
|
|
|
915
915
|
)
|
|
916
916
|
|
|
917
917
|
tutorial.add_step(
|
|
918
|
-
window.
|
|
918
|
+
window.graphics_widget,
|
|
919
919
|
"When it comes to making networks, there are three major modalities that NetTracer3D offers.",
|
|
920
920
|
highlight_type=None,
|
|
921
921
|
message_position="bottom"
|
|
922
922
|
)
|
|
923
923
|
|
|
924
924
|
tutorial.add_step(
|
|
925
|
-
window.
|
|
925
|
+
window.graphics_widget,
|
|
926
926
|
"The first is the 'connectivity network', where your node objects are connected via a secondary structure, deemed 'edges'. For example, we can evaluate how groups of segmented cell aggregates are connected via vasculature.",
|
|
927
927
|
highlight_type=None,
|
|
928
928
|
message_position="bottom"
|
|
@@ -942,7 +942,7 @@ def setup_start_tutorial(window):
|
|
|
942
942
|
message_position="top")
|
|
943
943
|
|
|
944
944
|
tutorial.add_step(
|
|
945
|
-
window.
|
|
945
|
+
window.graphics_widget,
|
|
946
946
|
"The second modality is making networks directly from branched structures. First, you would provide a binary segmentation of a branching structure like a nerve or a blood vessel. Next, you can algorithmically label the branches in NetTracer3D.",
|
|
947
947
|
highlight_type=None,
|
|
948
948
|
message_position="bottom"
|
|
@@ -962,14 +962,14 @@ def setup_start_tutorial(window):
|
|
|
962
962
|
)
|
|
963
963
|
|
|
964
964
|
tutorial.add_step(
|
|
965
|
-
window.
|
|
965
|
+
window.graphics_widget,
|
|
966
966
|
"Labeled branches can be turned into two types of networks. The first way is to connect the branchpoints. The second is to connect the branches themselves, just based on what other branches they come off of.",
|
|
967
967
|
highlight_type=None,
|
|
968
968
|
message_position="bottom"
|
|
969
969
|
)
|
|
970
970
|
|
|
971
971
|
tutorial.add_step(
|
|
972
|
-
window.
|
|
972
|
+
window.graphics_widget,
|
|
973
973
|
"The final modality is making networks based on proximity. This is an option to evaluate spatial clusters in your image, for example, deciphering what sort of groups a set of cells are arranged in. This would be an ideal way to analyze a multiplexed image with a lot of different channels bearing cellular fluorescent labels, for example.",
|
|
974
974
|
highlight_type=None,
|
|
975
975
|
message_position="bottom"
|
|
@@ -1129,7 +1129,7 @@ def setup_basics_tutorial(window):
|
|
|
1129
1129
|
|
|
1130
1130
|
# Step 1: Welcome
|
|
1131
1131
|
tutorial.add_step(
|
|
1132
|
-
window.
|
|
1132
|
+
window.graphics_widget,
|
|
1133
1133
|
"This tutorial will guide you through the main features of the GUI window. Click 'Next' or use 'Right-Click' to continue.",
|
|
1134
1134
|
highlight_type="rect",
|
|
1135
1135
|
message_position="bottom"
|
|
@@ -1137,28 +1137,28 @@ def setup_basics_tutorial(window):
|
|
|
1137
1137
|
|
|
1138
1138
|
# Step 2: Canvas explanation
|
|
1139
1139
|
tutorial.add_step(
|
|
1140
|
-
window.
|
|
1140
|
+
window.graphics_widget,
|
|
1141
1141
|
"This canvas is where your loaded images will render.",
|
|
1142
1142
|
highlight_type="rect",
|
|
1143
1143
|
message_position="bottom"
|
|
1144
1144
|
)
|
|
1145
1145
|
|
|
1146
1146
|
tutorial.add_step(
|
|
1147
|
-
window.
|
|
1147
|
+
window.graphics_widget,
|
|
1148
1148
|
"Clicking a node or edge in this canvas will select it (if the nodes or edges channels are set as the 'active channel', respectively). Click and drag to select multiple objects. This is intended mainly for segmented, labeled data rather than interacting directly with raw images.",
|
|
1149
1149
|
highlight_type="rect",
|
|
1150
1150
|
message_position="bottom"
|
|
1151
1151
|
)
|
|
1152
1152
|
|
|
1153
1153
|
tutorial.add_step(
|
|
1154
|
-
window.
|
|
1154
|
+
window.graphics_widget,
|
|
1155
1155
|
"Selected objects will be highlighted yellow and can be used for certain functions. Clicking a background val in an image (ie voxel with value 0) will deselect your objects.",
|
|
1156
1156
|
highlight_type="rect",
|
|
1157
1157
|
message_position="bottom"
|
|
1158
1158
|
)
|
|
1159
1159
|
|
|
1160
1160
|
tutorial.add_step(
|
|
1161
|
-
window.
|
|
1161
|
+
window.graphics_widget,
|
|
1162
1162
|
"Use right click to interact with highlighted objects (ie, delete them or merge them into one object); or rather to select objects algorithmically (for example, the neighbors of a node in your network)",
|
|
1163
1163
|
highlight_type="rect",
|
|
1164
1164
|
message_position="bottom"
|
|
@@ -1287,11 +1287,19 @@ def setup_basics_tutorial(window):
|
|
|
1287
1287
|
highlight_type="rect",
|
|
1288
1288
|
message_position="top"
|
|
1289
1289
|
)
|
|
1290
|
+
|
|
1291
|
+
# Data Tables
|
|
1292
|
+
tutorial.add_step(
|
|
1293
|
+
window.network_graph_button,
|
|
1294
|
+
"Similarly the network graph will allow you top render your network in a dedicated viewer that is interactable and linked with the main display window..",
|
|
1295
|
+
highlight_type="rect",
|
|
1296
|
+
message_position="top"
|
|
1297
|
+
)
|
|
1290
1298
|
|
|
1291
1299
|
# The actual table
|
|
1292
1300
|
tutorial.add_step(
|
|
1293
1301
|
window.network_table,
|
|
1294
|
-
"This table displays your network data. You can click rows to highlight corresponding elements in the image, and sort columns by clicking headers. Right click to export any tables in spreadsheet format, or in a format for a few other types of network analysis software.",
|
|
1302
|
+
"This table view displays your network data. You can click rows to highlight corresponding elements in the image, and sort columns by clicking headers. The graph view allows you to evaluate network connectivity and highlight those items in your main display window. Right click to export any tables in spreadsheet format, or in a format for a few other types of network analysis software.",
|
|
1295
1303
|
highlight_type="rect",
|
|
1296
1304
|
message_position="left"
|
|
1297
1305
|
)
|
|
@@ -1324,6 +1332,13 @@ def setup_basics_tutorial(window):
|
|
|
1324
1332
|
message_position="bottom"
|
|
1325
1333
|
)
|
|
1326
1334
|
|
|
1335
|
+
tutorial.add_step(
|
|
1336
|
+
window.threed_button,
|
|
1337
|
+
"This button can be used to create a 3D display of the current data. This can be called with additional optional settings from the 'Image' menu as well.",
|
|
1338
|
+
highlight_type="circle",
|
|
1339
|
+
message_position="bottom"
|
|
1340
|
+
)
|
|
1341
|
+
|
|
1327
1342
|
# File Menu - show where to load data
|
|
1328
1343
|
tutorial.add_step(
|
|
1329
1344
|
lambda: window.menuBar(),
|
|
@@ -1417,7 +1432,7 @@ def setup_file_tutorial(window):
|
|
|
1417
1432
|
tutorial.add_step(
|
|
1418
1433
|
MenuHelper.create_submenu_action_rect_getter(window, "File", "Save As", "Save Nodes As"),
|
|
1419
1434
|
f"""--Saving occurs from the SaveAs menu.
|
|
1420
|
-
\n\n--Use 'Save
|
|
1435
|
+
\n\n--Use 'Save Current Session As' as the primary save function. This will dump all the relevant properties to a folder. First, you will be prompted to select a folder on your computer. Next, you will enter the name of a new folder to create in the aforementioned parent folder. All the outputs will be saved to this new folder.
|
|
1421
1436
|
\n\n--The other SaveAs options can be used to save any of the image channels as a .tif.""",
|
|
1422
1437
|
highlight_type=None,
|
|
1423
1438
|
message_position="top_right",
|
|
@@ -1431,9 +1446,9 @@ def setup_file_tutorial(window):
|
|
|
1431
1446
|
|
|
1432
1447
|
# Step 3: Point to Image submenu
|
|
1433
1448
|
tutorial.add_step(
|
|
1434
|
-
MenuHelper.create_submenu_action_rect_getter(window, "File", "Load", "Load
|
|
1449
|
+
MenuHelper.create_submenu_action_rect_getter(window, "File", "Load", "Load Previous Session"),
|
|
1435
1450
|
f"""--Loading occurs from the load menu. Acceptable image types are .tif, .tiff, .nii, .png, .jpeg, and .jpg.
|
|
1436
|
-
\n\n--'Load
|
|
1451
|
+
\n\n--'Load Previous Session' can be used to load in an entire previously saved session, assuming it had been saved with the corresponding 'Save Current Session' method. Navigate your way to the directory the 'Current Session' dumped to. Select it to reload all properties within.
|
|
1437
1452
|
\n\n--Use 'load nodes' to load an image into the nodes channel. Similarly, use load edges to load edges, and either of the load overlays to load the overlays.
|
|
1438
1453
|
\n\n--Use 'load network' to load your saved network data from .csv or .xlsx format. Note this will expect to see the corresponding spreadsheet in the layout that NetTracer3D saves it.
|
|
1439
1454
|
\n\n--'Loading from the excel helper' opens a secondary gui where (mainly node identities) can be reassigned with a set of string keywords. For example, a node with identity 'x' and 'y' can be configured to be loaded as 'identity xy'
|
|
@@ -1627,12 +1642,44 @@ def setup_connectivity_tutorial(window):
|
|
|
1627
1642
|
action=MenuHelper.create_widget_interaction(tutorial, 'con_dialog', 'remove_trunk', 'setText("")')
|
|
1628
1643
|
)
|
|
1629
1644
|
|
|
1645
|
+
tutorial.add_step(
|
|
1646
|
+
MenuHelper.create_widget_getter(tutorial, 'con_dialog', 'voronoi_safe'),
|
|
1647
|
+
"The next few options present alternate ways to handle the trunk/edges if desired. Selecting this 'Auto-Trunk' method will make edge elements that exist as plexuses between nodes simplify themselves to make local connections but avoid more distant connections that have more local connectivity available. This is done by first computing the normal network, then computing a second network where the search regions are fully maxed out (and therefore naturally split trunks up; note, this step will not use parallel dilation), then pruning the second network to drop connections that don't exist in the first region. As such, it will be somewhat slower if enabled.",
|
|
1648
|
+
highlight_type=None,
|
|
1649
|
+
message_position="beside",
|
|
1650
|
+
pre_action=MenuHelper.create_widget_interaction(tutorial, 'con_dialog', 'voronoi_safe', 'click()'),
|
|
1651
|
+
action = MenuHelper.create_widget_interaction(tutorial, 'con_dialog', 'voronoi_safe', 'toggle()')
|
|
1652
|
+
)
|
|
1653
|
+
|
|
1654
|
+
tutorial.add_step(
|
|
1655
|
+
MenuHelper.create_widget_getter(tutorial, 'con_dialog', 'labeled_branches'),
|
|
1656
|
+
"The 'Pre-labeled edges' option will allow you to use pre-made edge labels, such as if you had previously labeled the branches of your edges. Instead of just joining nodes together, all edge labels will participate as nodes as well. This can be a way to visualize how branch-like structures in your edges interact with your main node objects.",
|
|
1657
|
+
highlight_type=None,
|
|
1658
|
+
message_position="beside",
|
|
1659
|
+
pre_action=MenuHelper.create_widget_interaction(tutorial, 'con_dialog', 'labeled_branches', 'click()'),
|
|
1660
|
+
action = MenuHelper.create_widget_interaction(tutorial, 'con_dialog', 'labeled_branches', 'toggle()')
|
|
1661
|
+
)
|
|
1662
|
+
|
|
1663
|
+
tutorial.add_step(
|
|
1664
|
+
MenuHelper.create_widget_getter(tutorial, 'con_dialog', 'edge_node'),
|
|
1665
|
+
"The 'Convert Edges to Nodes' option will make your edges become nodes. This can be a good way to visualize direct connectivity paths, and is a robust way to mitigate bias in what is or isn't a trunk. However, the network dynamics will be altered by edge inclusion, resulting in much less node clusters in favor of edge-derived hubs. You can also do this from the modify network after the calculation has been done.",
|
|
1666
|
+
highlight_type=None,
|
|
1667
|
+
message_position="beside",
|
|
1668
|
+
pre_action=MenuHelper.create_widget_interaction(tutorial, 'con_dialog', 'edge_node', 'click()'),
|
|
1669
|
+
action = MenuHelper.create_widget_interaction(tutorial, 'con_dialog', 'edge_node', 'toggle()')
|
|
1670
|
+
)
|
|
1671
|
+
|
|
1672
|
+
|
|
1673
|
+
|
|
1674
|
+
"""
|
|
1675
|
+
|
|
1630
1676
|
tutorial.add_step(
|
|
1631
1677
|
MenuHelper.create_widget_getter(tutorial, 'con_dialog', 'inners'),
|
|
1632
1678
|
"Deselecting this button will have the system not consider 'inner edges'. Inner edges are portions of your edge image that exist solely within nodes (as well as their expanded search regions). You can deselect this to ignore inner connections between within node clusters, for example if you only wanted to consider more distal connections to get a simpler network. However, I would recommend keeping this enabled unless you had a good reason to not.",
|
|
1633
1679
|
highlight_type=None,
|
|
1634
1680
|
message_position="beside",
|
|
1635
1681
|
pre_action=MenuHelper.create_widget_interaction(tutorial, 'con_dialog', 'inners', 'click()'))
|
|
1682
|
+
"""
|
|
1636
1683
|
|
|
1637
1684
|
tutorial.add_step(
|
|
1638
1685
|
MenuHelper.create_widget_getter(tutorial, 'con_dialog', 'down_factor'),
|
|
@@ -1645,7 +1692,8 @@ def setup_connectivity_tutorial(window):
|
|
|
1645
1692
|
|
|
1646
1693
|
tutorial.add_step(
|
|
1647
1694
|
MenuHelper.create_widget_getter(tutorial, 'con_dialog', 'fastdil'),
|
|
1648
|
-
"Enable the fast search button to use a slightly alternate algorithm for the node search step that is faster. This algorithm uses a parallelized distance transform to create a binary search region which is a lot faster if you have a lot of CPU cores. It then uses flooding to label the binary search region, which leads to slightly rough labeling where two search regions meet. When disabled, a non-parallel distance transform is used, which can be slower but always has exact labels where two search regions meet. I recommend enabling this for larger images and disabling it for smaller ones.",
|
|
1695
|
+
"Enable the fast search button to use a slightly alternate algorithm for the node search step that is faster. This algorithm uses a parallelized distance transform to create a binary search region which is a lot faster if you have a lot of CPU cores. It then uses flooding to label the binary search region, which leads to slightly rough labeling where two search regions meet. When disabled, a non-parallel distance transform is used, which can be slower but always has exact labels where two search regions meet. I recommend enabling this for larger images and disabling it for smaller ones. If your search region is very large the fast search may be actually slower but there isn't often a practical region to use immense search regions anyway.",
|
|
1696
|
+
highlight_type=None,
|
|
1649
1697
|
message_position="beside",
|
|
1650
1698
|
pre_action=MenuHelper.create_widget_interaction(tutorial, 'con_dialog', 'fastdil', 'click()'),
|
|
1651
1699
|
action=MenuHelper.create_widget_interaction(tutorial, 'con_dialog', 'fastdil', 'toggle()')
|
|
@@ -1745,15 +1793,16 @@ def setup_branch_tutorial(window):
|
|
|
1745
1793
|
|
|
1746
1794
|
tutorial.add_step(
|
|
1747
1795
|
MenuHelper.create_widget_getter(tutorial, 'branch_dialog', 'fix2'),
|
|
1748
|
-
"The
|
|
1796
|
+
"The first auto-correction option will automatically merge any internal labels that arise with their outer-neighbors. This is something that can occasionally happen with fat, trunk-like branches that are tricky to algorithmically decipher. I have found that this merge handles these issues quite well, so this option is enabled by default. An alternate option will make the internal labels only merge with external structures that are not 'branch-like'. This is a good thing to enable if you are also enabling the 'reunify main branches' correction, as it will stop long branches from merging with core-like elements.",
|
|
1749
1797
|
highlight_type=None,
|
|
1750
1798
|
message_position="beside",
|
|
1751
|
-
pre_action=MenuHelper.create_widget_interaction(tutorial, 'branch_dialog', 'fix2', '
|
|
1799
|
+
pre_action=MenuHelper.create_widget_interaction(tutorial, 'branch_dialog', 'fix2', 'showPopup()'),
|
|
1800
|
+
action=MenuHelper.create_widget_interaction(tutorial, 'branch_dialog', 'fix2', 'hidePopup()')
|
|
1752
1801
|
)
|
|
1753
1802
|
|
|
1754
1803
|
tutorial.add_step(
|
|
1755
1804
|
MenuHelper.create_widget_getter(tutorial, 'branch_dialog', 'fix3'),
|
|
1756
|
-
"
|
|
1805
|
+
"The second auto-correction step will automatically correct any branches that aren't contiguous in space. Rarely (Depending on the segmentation, really) a branch can initially be labeled non-contiguously, which is usually not correct. This is because the 'meat' of any branch is at first labeled based on which internal filament it's closest to. So if you have a very wide branch it may rarely aquire labels of nearby smaller branches across gaps. Enabling this will split those labels into seperate regions as to not confound the connectivity graph. The largest component is considered the 'correct one' and keeps its label, while smaller components inherit the label of the largest shared border of a 'real' branch they are bordering. It is enabled here by default to mitigate any potential errors, although note this does not apply to the branchpoint networks since they don't actually utilize the branches themselves.",
|
|
1757
1806
|
highlight_type=None,
|
|
1758
1807
|
message_position="beside",
|
|
1759
1808
|
pre_action=MenuHelper.create_widget_interaction(tutorial, 'branch_dialog', 'fix3', 'click()')
|
|
@@ -1847,6 +1896,7 @@ def setup_branch_tutorial(window):
|
|
|
1847
1896
|
action=MenuHelper.create_widget_interaction(tutorial, 'gen_dialog', 'branch_removal', 'setText("")')
|
|
1848
1897
|
)
|
|
1849
1898
|
|
|
1899
|
+
"""
|
|
1850
1900
|
tutorial.add_step(
|
|
1851
1901
|
MenuHelper.create_widget_getter(tutorial, 'gen_dialog', 'auto'),
|
|
1852
1902
|
"This 'attempt to auto correct skeleton looping' option should generally be enabled for 3D data. In short it applies an extra algorithmic step to improve the branch detection algorithm. However, this does not really apply to 2D data. It will be enabled by default for 3D data and disabled by default for 2D data.",
|
|
@@ -1855,6 +1905,7 @@ def setup_branch_tutorial(window):
|
|
|
1855
1905
|
pre_action=MenuHelper.create_widget_interaction(tutorial, 'gen_dialog', 'auto', 'click()'),
|
|
1856
1906
|
action=MenuHelper.create_widget_interaction(tutorial, 'gen_dialog', 'auto', 'toggle()')
|
|
1857
1907
|
)
|
|
1908
|
+
"""
|
|
1858
1909
|
|
|
1859
1910
|
tutorial.add_step(
|
|
1860
1911
|
MenuHelper.create_widget_getter(tutorial, 'gen_dialog', 'comp_dil'),
|
|
@@ -2156,14 +2207,14 @@ def setup_seg_tutorial(window):
|
|
|
2156
2207
|
)
|
|
2157
2208
|
|
|
2158
2209
|
tutorial.add_step(
|
|
2159
|
-
window.
|
|
2210
|
+
window.graphics_widget,
|
|
2160
2211
|
"You will mark these regions directly on the canvas.",
|
|
2161
2212
|
highlight_type="rect",
|
|
2162
2213
|
message_position="top_left"
|
|
2163
2214
|
)
|
|
2164
2215
|
|
|
2165
2216
|
tutorial.add_step(
|
|
2166
|
-
window.
|
|
2217
|
+
window.graphics_widget,
|
|
2167
2218
|
"The program will use your markings to train itself. When you train a model, it will learn to segment out regions that look like those you marked as foreground, while ignoring regions that you marked as background.",
|
|
2168
2219
|
highlight_type="rect",
|
|
2169
2220
|
message_position="top_left"
|
|
@@ -2224,7 +2275,7 @@ def setup_seg_tutorial(window):
|
|
|
2224
2275
|
|
|
2225
2276
|
tutorial.add_step(
|
|
2226
2277
|
None,
|
|
2227
|
-
"At some point you'll reach some kind of ceiling where additional training data won't really help more. This might take 20
|
|
2278
|
+
"At some point you'll reach some kind of ceiling where additional training data won't really help more. This might take 20 minutes of training or so. So try to end the training session by then, or earlier if it looks satisfactory.",
|
|
2228
2279
|
highlight_type="rect",
|
|
2229
2280
|
message_position="top_left"
|
|
2230
2281
|
)
|
|
@@ -2259,7 +2310,7 @@ def setup_seg_tutorial(window):
|
|
|
2259
2310
|
|
|
2260
2311
|
tutorial.add_step(
|
|
2261
2312
|
None,
|
|
2262
|
-
"Likewise, 'Load Model' can be used to reopen a saved model. You can train
|
|
2313
|
+
"Likewise, 'Load Model' can be used to reopen a saved model. You can train on top of an old model to have it combine all the training data, although note the model might slow down the more you train on it.",
|
|
2263
2314
|
highlight_type="rect",
|
|
2264
2315
|
message_position="top_left"
|
|
2265
2316
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nettracer3d
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.6
|
|
4
4
|
Summary: Scripts for intializing and analyzing networks from segmentations of three dimensional images.
|
|
5
5
|
Author-email: Liam McLaughlin <liamm@wustl.edu>
|
|
6
6
|
Project-URL: Documentation, https://nettracer3d.readthedocs.io/en/latest/
|
|
@@ -24,10 +24,10 @@ Requires-Dist: pandas
|
|
|
24
24
|
Requires-Dist: tifffile
|
|
25
25
|
Requires-Dist: qtrangeslider
|
|
26
26
|
Requires-Dist: PyQt6
|
|
27
|
+
Requires-Dist: pyqtgraph
|
|
27
28
|
Requires-Dist: scikit-learn
|
|
28
29
|
Requires-Dist: setuptools
|
|
29
30
|
Requires-Dist: umap-learn
|
|
30
|
-
Requires-Dist: edt
|
|
31
31
|
Provides-Extra: cuda11
|
|
32
32
|
Requires-Dist: cupy-cuda11x; extra == "cuda11"
|
|
33
33
|
Provides-Extra: cuda12
|
|
@@ -38,9 +38,15 @@ Provides-Extra: cellpose
|
|
|
38
38
|
Requires-Dist: cellpose[GUI]; extra == "cellpose"
|
|
39
39
|
Provides-Extra: viz
|
|
40
40
|
Requires-Dist: napari; extra == "viz"
|
|
41
|
+
Provides-Extra: rec
|
|
42
|
+
Requires-Dist: napari; extra == "rec"
|
|
43
|
+
Requires-Dist: edt; extra == "rec"
|
|
44
|
+
Provides-Extra: edt
|
|
45
|
+
Requires-Dist: edt; extra == "edt"
|
|
41
46
|
Provides-Extra: all
|
|
42
47
|
Requires-Dist: cellpose[GUI]; extra == "all"
|
|
43
48
|
Requires-Dist: napari; extra == "all"
|
|
49
|
+
Requires-Dist: edt; extra == "all"
|
|
44
50
|
Dynamic: license-file
|
|
45
51
|
|
|
46
52
|
NetTracer3D is a python package developed for both 2D and 3D analysis of microscopic images in the .tif file format. It supports generation of 3D networks showing the relationships between objects (or nodes) in three dimensional space, either based on their own proximity or connectivity via connecting objects such as nerves or blood vessels. In addition to these functionalities are several advanced 3D data processing algorithms, such as labeling of branched structures or abstraction of branched structures into networks. Note that nettracer3d uses segmented data, which can be segmented from other softwares such as ImageJ and imported into NetTracer3D, although it does offer its own segmentation via intensity and volumetric thresholding, or random forest machine learning segmentation. NetTracer3D currently has a fully functional GUI. To use the GUI, after installing the nettracer3d package via pip, enter the command 'nettracer3d' in your command prompt:
|
|
@@ -56,23 +62,54 @@ Please see: https://nettracer3d.readthedocs.io/en/latest/
|
|
|
56
62
|
Please see: https://www.youtube.com/watch?v=_4uDy0mzG94&list=PLsrhxiimzKJMZ3_gTWkfrcAdJQQobUhj7
|
|
57
63
|
|
|
58
64
|
|
|
59
|
-
---
|
|
65
|
+
--- Installing as a Python package ---
|
|
60
66
|
|
|
61
|
-
To install nettracer3d,
|
|
67
|
+
1. **Get Python and Pip on your path**: To install nettracer3d, first install Python version 3.12. Make sure the Python installation installs pip, and that both Python and pip are available on your PATH. I recommend installing Python using the installer which is available here. Make sure to check the option to 'add Python to PATH' when it appears: https://www.python.org/downloads/
|
|
62
68
|
|
|
63
|
-
|
|
69
|
+
|
|
70
|
+
2. **Base Package**: Next, use this command in your command terminal
|
|
71
|
+
|
|
72
|
+
* pip install nettracer3d
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
3. **For 3D Displays**: Or if you also want Napari for 3D displays:
|
|
76
|
+
|
|
77
|
+
* pip install nettracer3d[viz]
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
4. **Optional Performance Boost**: If you are trying to process large images, you may also want to include the 'edt' module in your package. This will allow parallelized CPU calculations for several of the search functions which can increase their speed by an order of magnitude or more depending on how many cores your CPU has. This can be a major benefit if you have a strong CPU and sufficient RAM. It requires an extra pre-installation step, thus is not included by default. You will also have to install the C++ build tools from windows. Please head to this link, then download and run the installer: https://visualstudio.microsoft.com/visual-cpp-build-tools/. In the menu of the installer, select the 'Desktop Development with C++' option, then proceed to download/install it using the installation menu. You will likely want to be using the Python distributed from the actual Python website and not the windows store (or elsewhere) or the edt module may not work properly. To bundle with edt use:
|
|
81
|
+
|
|
82
|
+
* pip install nettracer3d[edt]
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
5. **Recommended full package**: Or if you want to just get both edt and napari at once:
|
|
86
|
+
|
|
87
|
+
* pip install nettracer3d[rec]
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
6. Likewise, if you already installed the default version, you can add napari and/or edt with just:
|
|
91
|
+
|
|
92
|
+
* pip install edt
|
|
93
|
+
* pip install napari
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
--- Installing as a Python package in Anaconda---
|
|
64
97
|
|
|
65
98
|
I recommend installing the program as an Anaconda package to ensure its modules are work together on your specific system:
|
|
66
99
|
(Install anaconda at the link below, set up a new python env for nettracer3d, then use the same pip command).
|
|
67
100
|
|
|
68
101
|
https://www.anaconda.com/download?utm_source=anacondadocs&utm_medium=documentation&utm_campaign=download&utm_content=installwindows
|
|
69
102
|
|
|
103
|
+
|
|
104
|
+
--- Using the downloadable version ---
|
|
105
|
+
|
|
70
106
|
Alternatively, you can download a compiled .exe of version 1.2.7 here: https://doi.org/10.5281/zenodo.17873800
|
|
71
107
|
|
|
72
108
|
Unzip the folder, then double click the NetTracer3D executable to run the program. Note that this version will be missing a few features compared to the Python package, namely GPU segmentation support and the ability to print updates to the command window. It will also not be updated as often.
|
|
73
109
|
|
|
74
|
-
|
|
75
|
-
|
|
110
|
+
|
|
111
|
+
--- Optional Packages ---
|
|
112
|
+
|
|
76
113
|
I recommend including Napari (Chi-Li Chiu, Nathan Clack, the napari community, napari: a Python Multi-Dimensional Image Viewer Platform for the Research Community, Microscopy and Microanalysis, Volume 28, Issue S1, 1 August 2022, Pages 1576–1577, https://doi.org/10.1017/S1431927622006328) in the download as well, which allows NetTracer3D to use 3D displays. The standard package only comes with its native 2D slice display window.
|
|
77
114
|
If Napari is present, all 3D images and overlays from NetTracer3D can be easily displayed in 3D with a click of a button. To package with Napari, use this install command instead:
|
|
78
115
|
|
|
@@ -85,13 +122,13 @@ To include Cellpose3 in the install, use this command:
|
|
|
85
122
|
|
|
86
123
|
pip install nettracer3d[cellpose]
|
|
87
124
|
|
|
88
|
-
Alternatively,
|
|
125
|
+
Alternatively, Napari, Cellpose, and edt can be included in the package with this command: (Or they can be independently installed with pip from the base package env)
|
|
89
126
|
|
|
90
127
|
|
|
91
128
|
pip install nettracer3d[all]
|
|
92
129
|
|
|
93
|
-
|
|
94
|
-
|
|
130
|
+
|
|
131
|
+
--- GPU ---
|
|
95
132
|
NetTracer3D is mostly CPU-bound, but a few functions can optionally use the GPU. To install optional GPU functionalities, first set up a CUDA toolkit that runs with the GPU on your machine. This requires an NVIDIA GPU. Then, find your GPUs compatible CUDA toolkit and install it with the auto-installer from the NVIDIA website: https://developer.nvidia.com/cuda-toolkit
|
|
96
133
|
|
|
97
134
|
With a CUDA toolkit installed, use:
|
|
@@ -118,12 +155,7 @@ NetTracer3D is freely available for academic and nonprofit use and can obtained
|
|
|
118
155
|
|
|
119
156
|
NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
|
|
120
157
|
|
|
121
|
-
-- Version 1.
|
|
158
|
+
-- Version 1.3.6 Updates --
|
|
122
159
|
|
|
123
|
-
* Added
|
|
124
|
-
*
|
|
125
|
-
* Now depends on the 'edt' package (which does the above).
|
|
126
|
-
* Removed dependency on nibabel (which was just being used to open .nii files). .nii files can still be opened if nibabel is installed manually.
|
|
127
|
-
* Added option to not show numerical labels when displaying network graph.
|
|
128
|
-
|
|
129
|
-
|
|
160
|
+
* Added more options for styles of network graph renders.
|
|
161
|
+
* Bug fixes
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
nettracer3d/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
nettracer3d/branch_stitcher.py,sha256=rCTeh-28o7yN6ghYwxVSfrn2oc-TiPOm1xB3xJ5RWbw,21216
|
|
3
|
+
nettracer3d/cellpose_manager.py,sha256=NfRqW6Zl7yRU4qHCS_KjmR0R6QANSSgCO0_dr-eivxg,6694
|
|
4
|
+
nettracer3d/community_extractor.py,sha256=sDnPyoaAZfFTBNkKDHmmkpT91D5ZC2ImR6LdEhAb3ww,31778
|
|
5
|
+
nettracer3d/endpoint_joiner.py,sha256=ioR-hM_NxPjaEG1K9yucsv9kFp_-TgqKDQrjp9FYdiQ,9933
|
|
6
|
+
nettracer3d/excelotron.py,sha256=aNof6k-DgMxVyFgsl3ltSCxG4vZW49cuvCBzfzhYhUY,75072
|
|
7
|
+
nettracer3d/filaments.py,sha256=tGuL-KZahVF95AVy75u8i0d7olOjCWB0TtT3EVc-geM,54689
|
|
8
|
+
nettracer3d/histos.py,sha256=gEV3v_H8zl_tZVJHr00xdyuL2hAIfuGiBho4Xj_IlSo,61539
|
|
9
|
+
nettracer3d/modularity.py,sha256=B08ZUw_C_8qqLIk9fHhKslxUgwQKt9pndY82eHtSIf8,19772
|
|
10
|
+
nettracer3d/morphology.py,sha256=eusirbmDFQD__tlhkwZbctd8N4AARXVU0IGowr7M8cA,23297
|
|
11
|
+
nettracer3d/neighborhoods.py,sha256=Zk5NuRYVLORR3fv1u2YRZ1gjBPO9hRrCgod06pqyj1E,53188
|
|
12
|
+
nettracer3d/nettracer.py,sha256=f0ycXvUDG3nfSEUScpAPIK9Z8p2tKCk3YfsmgDpeEqU,298826
|
|
13
|
+
nettracer3d/nettracer_gui.py,sha256=IQ5PCe1HYcTtforu1vQTMSzXisZIXkgPbDm3zJoVqNk,708750
|
|
14
|
+
nettracer3d/network_analysis.py,sha256=UwS5ISZzjKe8SrSltNTqOMaqsj7ZA6x065PC8bCbaTE,46430
|
|
15
|
+
nettracer3d/network_draw.py,sha256=1Dj6VSMtMZbMxmrA7bWGxaLChqvM17xnZo85EUgG2PM,14291
|
|
16
|
+
nettracer3d/network_graph_widget.py,sha256=rUPz4wg2KTy2PRuMxBlUrCT7-X50c32UnROweshYfp4,88551
|
|
17
|
+
nettracer3d/node_draw.py,sha256=Md12OiBtEyQmF2W_enO4qrSPFTRfoV4sOCMeEEdTNz4,10488
|
|
18
|
+
nettracer3d/painting.py,sha256=10XBjDqfOb1nTbGgIicOpoeIKRZZ4al2uFtrv-8MIBE,16760
|
|
19
|
+
nettracer3d/proximity.py,sha256=xvJLt61nTsKMdpJ0aiwJsB5vPriO34KG0LQwDjyfhC8,41410
|
|
20
|
+
nettracer3d/run.py,sha256=xYeaAc8FCx8MuzTGyL3NR3mK7WZzffAYAH23bNRZYO4,127
|
|
21
|
+
nettracer3d/segmenter.py,sha256=UBq4nPJQJfDxMUlOeQAJBpoUIT3xymQ1o40OhfV-dT0,72776
|
|
22
|
+
nettracer3d/segmenter_GPU.py,sha256=ootY0lcfaWj0pIVN7Nh0ElEwQ6xW5QgnuUq2i0G4Qyg,79966
|
|
23
|
+
nettracer3d/simple_network.py,sha256=1InpqSXfae_L-6lmf8lXgV7n_rk7Porg1hc_in9vkHg,10499
|
|
24
|
+
nettracer3d/smart_dilate.py,sha256=1UzLnX5LCj6OuFIy7_gHcZe9OIHkVJdIkZJDuJNqyYc,32009
|
|
25
|
+
nettracer3d/stats.py,sha256=0YwrVLeEvll3PlbL5-0_9dstldr48PvxJrQm-PiC8jY,36607
|
|
26
|
+
nettracer3d/tutorial.py,sha256=cxVbs-YvG3TS-Zi8wfmdP1aCAPqxtPcCeYqn3CJxaDw,155639
|
|
27
|
+
nettracer3d-1.3.6.dist-info/licenses/LICENSE,sha256=_Wg4zyCtT18lXBCXRov17IEop_-7z1OFo6o3JTzQj3g,568
|
|
28
|
+
nettracer3d-1.3.6.dist-info/METADATA,sha256=LG8ufBcsw__XB0oHlSWryMTiB93u6Q-5TEqzGl7IvMw,9439
|
|
29
|
+
nettracer3d-1.3.6.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
30
|
+
nettracer3d-1.3.6.dist-info/entry_points.txt,sha256=Nx1rr_0QhJXDBHAQg2vcqCzLMKBzSHfwy3xwGkueVyc,53
|
|
31
|
+
nettracer3d-1.3.6.dist-info/top_level.txt,sha256=zsYy9rZwirfCEOubolhee4TyzqBAL5gSUeFMzhFTX8c,12
|
|
32
|
+
nettracer3d-1.3.6.dist-info/RECORD,,
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
nettracer3d/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
nettracer3d/branch_stitcher.py,sha256=nF-5xtYowMcd55kSGv1CDLk31E-FMagy_wHC3hEq8mg,16667
|
|
3
|
-
nettracer3d/cellpose_manager.py,sha256=NfRqW6Zl7yRU4qHCS_KjmR0R6QANSSgCO0_dr-eivxg,6694
|
|
4
|
-
nettracer3d/community_extractor.py,sha256=rPXXWwMX05mfD_ogULEouLy8CST-aOaoSw45NhloKVg,31754
|
|
5
|
-
nettracer3d/excelotron.py,sha256=aNof6k-DgMxVyFgsl3ltSCxG4vZW49cuvCBzfzhYhUY,75072
|
|
6
|
-
nettracer3d/filaments.py,sha256=liuhikdRoANUmYA_hiPUPtDV-lYtR8wKbgnUVk55Hgs,43952
|
|
7
|
-
nettracer3d/modularity.py,sha256=HgaVQSVjgAX3LAfJeUL1ZZ3P3xGuALJpQHqtYrhgw5c,22762
|
|
8
|
-
nettracer3d/morphology.py,sha256=eusirbmDFQD__tlhkwZbctd8N4AARXVU0IGowr7M8cA,23297
|
|
9
|
-
nettracer3d/neighborhoods.py,sha256=Bje77gWzXRIYyXkDlnFQnbUALnIt8dheLXHVFQsAKuc,53156
|
|
10
|
-
nettracer3d/nettracer.py,sha256=g8yHaZW265dplYIobeurNPb07lv8MNecbEsyo7syI34,290233
|
|
11
|
-
nettracer3d/nettracer_gui.py,sha256=Zos0sCHs0S6vjxrk-lvSPpBXQQA_QiLGkis8S5KYd3k,745331
|
|
12
|
-
nettracer3d/network_analysis.py,sha256=YKRlhSpQbtztCdAIWbt3cFAQKgZWz36h3aLgD8nQAuk,45797
|
|
13
|
-
nettracer3d/network_draw.py,sha256=1Dj6VSMtMZbMxmrA7bWGxaLChqvM17xnZo85EUgG2PM,14291
|
|
14
|
-
nettracer3d/node_draw.py,sha256=Md12OiBtEyQmF2W_enO4qrSPFTRfoV4sOCMeEEdTNz4,10488
|
|
15
|
-
nettracer3d/painting.py,sha256=K_dwngivw80r-Yyg4btKMsWGn566ZE9PnrQl986uxJE,23497
|
|
16
|
-
nettracer3d/proximity.py,sha256=xvJLt61nTsKMdpJ0aiwJsB5vPriO34KG0LQwDjyfhC8,41410
|
|
17
|
-
nettracer3d/run.py,sha256=xYeaAc8FCx8MuzTGyL3NR3mK7WZzffAYAH23bNRZYO4,127
|
|
18
|
-
nettracer3d/segmenter.py,sha256=20ch_uLqedV9srwT1eL5eFs88ojkb2gELWJKgtYk2qk,72791
|
|
19
|
-
nettracer3d/segmenter_GPU.py,sha256=FwzevixleTUoRmwVa8jPPzW82RZoC6nL2eEeZ4-2ZR8,80015
|
|
20
|
-
nettracer3d/simple_network.py,sha256=7iSO7NYf0Ezeix-9ruRB5b2xXtgeOAoN7tM9SR4GtKw,10480
|
|
21
|
-
nettracer3d/smart_dilate.py,sha256=nxWxG8sHL0FHPOJIZGKFVKxPHwysvf6F-yhoGgajbQI,31377
|
|
22
|
-
nettracer3d/stats.py,sha256=0YwrVLeEvll3PlbL5-0_9dstldr48PvxJrQm-PiC8jY,36607
|
|
23
|
-
nettracer3d/tutorial.py,sha256=XzQ5IRQKTDLwjWdFG7rj6qmO_NGemcqYwRmH1GPhz3g,151509
|
|
24
|
-
nettracer3d-1.2.7.dist-info/licenses/LICENSE,sha256=_Wg4zyCtT18lXBCXRov17IEop_-7z1OFo6o3JTzQj3g,568
|
|
25
|
-
nettracer3d-1.2.7.dist-info/METADATA,sha256=OA35aSlV93IMQv5dB-wq8FludCZeFKYyhlHs16ucmXA,7925
|
|
26
|
-
nettracer3d-1.2.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
27
|
-
nettracer3d-1.2.7.dist-info/entry_points.txt,sha256=Nx1rr_0QhJXDBHAQg2vcqCzLMKBzSHfwy3xwGkueVyc,53
|
|
28
|
-
nettracer3d-1.2.7.dist-info/top_level.txt,sha256=zsYy9rZwirfCEOubolhee4TyzqBAL5gSUeFMzhFTX8c,12
|
|
29
|
-
nettracer3d-1.2.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|