nettracer3d 0.6.3__py3-none-any.whl → 0.6.4__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.
- nettracer3d/nettracer.py +45 -12
- nettracer3d/nettracer_gui.py +63 -23
- nettracer3d/network_analysis.py +6 -6
- {nettracer3d-0.6.3.dist-info → nettracer3d-0.6.4.dist-info}/METADATA +10 -5
- {nettracer3d-0.6.3.dist-info → nettracer3d-0.6.4.dist-info}/RECORD +9 -9
- {nettracer3d-0.6.3.dist-info → nettracer3d-0.6.4.dist-info}/WHEEL +1 -1
- {nettracer3d-0.6.3.dist-info → nettracer3d-0.6.4.dist-info}/entry_points.txt +0 -0
- {nettracer3d-0.6.3.dist-info → nettracer3d-0.6.4.dist-info}/licenses/LICENSE +0 -0
- {nettracer3d-0.6.3.dist-info → nettracer3d-0.6.4.dist-info}/top_level.txt +0 -0
nettracer3d/nettracer.py
CHANGED
|
@@ -751,6 +751,8 @@ def fill_holes_3d(array):
|
|
|
751
751
|
|
|
752
752
|
return holes_mask
|
|
753
753
|
|
|
754
|
+
print("Filling Holes...")
|
|
755
|
+
|
|
754
756
|
array = binarize(array)
|
|
755
757
|
inv_array = invert_array(array)
|
|
756
758
|
|
|
@@ -3270,7 +3272,10 @@ class Network_3D:
|
|
|
3270
3272
|
self._xy_scale = xy_scale
|
|
3271
3273
|
self._z_scale = z_scale
|
|
3272
3274
|
|
|
3273
|
-
|
|
3275
|
+
try:
|
|
3276
|
+
self.save_scaling(directory)
|
|
3277
|
+
except:
|
|
3278
|
+
pass
|
|
3274
3279
|
|
|
3275
3280
|
if search is None and ignore_search_region == False:
|
|
3276
3281
|
search = 0
|
|
@@ -3286,29 +3291,51 @@ class Network_3D:
|
|
|
3286
3291
|
if other_nodes is not None:
|
|
3287
3292
|
self.merge_nodes(other_nodes, label_nodes)
|
|
3288
3293
|
|
|
3289
|
-
|
|
3290
|
-
|
|
3294
|
+
try:
|
|
3295
|
+
self.save_nodes(directory)
|
|
3296
|
+
except:
|
|
3297
|
+
pass
|
|
3298
|
+
try:
|
|
3299
|
+
self.save_node_identities(directory)
|
|
3300
|
+
except:
|
|
3301
|
+
pass
|
|
3291
3302
|
|
|
3292
3303
|
if not ignore_search_region:
|
|
3293
3304
|
self.calculate_search_region(search, GPU = GPU, fast_dil = fast_dil, GPU_downsample = GPU_downsample)
|
|
3294
|
-
self._nodes = None
|
|
3305
|
+
#self._nodes = None # I originally put this here to micromanage RAM a little bit (it writes it to disk so I wanted to purge it from mem briefly but now idt thats necessary and I'd rather give it flexibility when lacking write permissions)
|
|
3295
3306
|
search = None
|
|
3296
|
-
|
|
3307
|
+
try:
|
|
3308
|
+
self.save_search_region(directory)
|
|
3309
|
+
except:
|
|
3310
|
+
pass
|
|
3297
3311
|
|
|
3298
3312
|
self.calculate_edges(edges, diledge = diledge, inners = inners, hash_inner_edges = hash_inners, search = search, remove_edgetrunk = remove_trunk, GPU = GPU, fast_dil = fast_dil, skeletonized = skeletonize)
|
|
3299
3313
|
del edges
|
|
3300
|
-
|
|
3314
|
+
try:
|
|
3315
|
+
self.save_edges(directory)
|
|
3316
|
+
except:
|
|
3317
|
+
pass
|
|
3301
3318
|
|
|
3302
3319
|
self.calculate_network(search = search, ignore_search_region = ignore_search_region)
|
|
3303
|
-
|
|
3320
|
+
|
|
3321
|
+
try:
|
|
3322
|
+
self.save_network(directory)
|
|
3323
|
+
except:
|
|
3324
|
+
pass
|
|
3304
3325
|
|
|
3305
3326
|
if self._nodes is None:
|
|
3306
3327
|
self.load_nodes(directory)
|
|
3307
3328
|
|
|
3308
3329
|
self.calculate_node_centroids(down_factor)
|
|
3309
|
-
|
|
3330
|
+
try:
|
|
3331
|
+
self.save_node_centroids(directory)
|
|
3332
|
+
except:
|
|
3333
|
+
pass
|
|
3310
3334
|
self.calculate_edge_centroids(down_factor)
|
|
3311
|
-
|
|
3335
|
+
try:
|
|
3336
|
+
self.save_edge_centroids(directory)
|
|
3337
|
+
except:
|
|
3338
|
+
pass
|
|
3312
3339
|
|
|
3313
3340
|
|
|
3314
3341
|
def draw_network(self, directory = None, down_factor = None, GPU = False):
|
|
@@ -3557,15 +3584,21 @@ class Network_3D:
|
|
|
3557
3584
|
list1 = self._network_lists[0] #Get network lists to change
|
|
3558
3585
|
list2 = self._network_lists[1]
|
|
3559
3586
|
list3 = self._network_lists[2]
|
|
3587
|
+
return1 = []
|
|
3588
|
+
return2 = []
|
|
3589
|
+
return3 = []
|
|
3560
3590
|
|
|
3561
3591
|
for i in range(len(list1)):
|
|
3562
3592
|
list1[i] = self.communities[list1[i]] #Set node at network list spot to its community instead
|
|
3563
3593
|
list2[i] = self.communities[list2[i]]
|
|
3564
|
-
if list1[i]
|
|
3565
|
-
|
|
3594
|
+
if list1[i] != list2[i]: #Avoid self - self connections
|
|
3595
|
+
return1.append(list1[i])
|
|
3596
|
+
return2.append(list2[i])
|
|
3597
|
+
return3.append(list3[i])
|
|
3598
|
+
|
|
3566
3599
|
|
|
3567
3600
|
|
|
3568
|
-
self.network_lists = [
|
|
3601
|
+
self.network_lists = [return1, return2, return3]
|
|
3569
3602
|
|
|
3570
3603
|
if self._nodes is not None:
|
|
3571
3604
|
self._nodes = update_array(self._nodes, inverted, targets = targets) #Set the array to match the new network
|
nettracer3d/nettracer_gui.py
CHANGED
|
@@ -325,7 +325,7 @@ class ImageViewerWindow(QMainWindow):
|
|
|
325
325
|
self.tabbed_data = TabbedDataWidget(self)
|
|
326
326
|
right_layout.addWidget(self.tabbed_data)
|
|
327
327
|
# Initialize data_table property to None - it will be set when tabs are added
|
|
328
|
-
self.data_table =
|
|
328
|
+
self.data_table = []
|
|
329
329
|
|
|
330
330
|
# Create table control panel
|
|
331
331
|
table_control = QWidget()
|
|
@@ -1814,6 +1814,7 @@ class ImageViewerWindow(QMainWindow):
|
|
|
1814
1814
|
new_xlim = [xdata - x_range, xdata + x_range]
|
|
1815
1815
|
new_ylim = [ydata - y_range, ydata + y_range]
|
|
1816
1816
|
|
|
1817
|
+
|
|
1817
1818
|
if (new_xlim[0] <= self.original_xlim[0] or
|
|
1818
1819
|
new_xlim[1] >= self.original_xlim[1] or
|
|
1819
1820
|
new_ylim[0] <= self.original_ylim[0] or
|
|
@@ -3228,6 +3229,9 @@ class ImageViewerWindow(QMainWindow):
|
|
|
3228
3229
|
self.highlight_overlay = None
|
|
3229
3230
|
except:
|
|
3230
3231
|
pass
|
|
3232
|
+
if not data:
|
|
3233
|
+
self.original_xlim = None
|
|
3234
|
+
self.original_ylim = None
|
|
3231
3235
|
continue
|
|
3232
3236
|
else:
|
|
3233
3237
|
old_shape = self.channel_data[i].shape[:3] #Ask user to resize images that are shaped differently
|
|
@@ -3987,7 +3991,7 @@ class CustomTableView(QTableView):
|
|
|
3987
3991
|
desc_action.triggered.connect(lambda checked, c=col: self.sort_table(c, ascending=False))
|
|
3988
3992
|
|
|
3989
3993
|
# Different menus for top and bottom tables
|
|
3990
|
-
if self
|
|
3994
|
+
if self in self.parent.data_table: # Top table
|
|
3991
3995
|
save_menu = context_menu.addMenu("Save As")
|
|
3992
3996
|
save_csv = save_menu.addAction("CSV")
|
|
3993
3997
|
save_excel = save_menu.addAction("Excel")
|
|
@@ -4096,7 +4100,7 @@ class CustomTableView(QTableView):
|
|
|
4096
4100
|
df = self.model()._data
|
|
4097
4101
|
|
|
4098
4102
|
# Get table name for the file dialog title
|
|
4099
|
-
if self
|
|
4103
|
+
if self in self.parent.data_table:
|
|
4100
4104
|
table_name = "Statistics"
|
|
4101
4105
|
elif self == self.parent.network_table:
|
|
4102
4106
|
table_name = "Network"
|
|
@@ -4105,7 +4109,7 @@ class CustomTableView(QTableView):
|
|
|
4105
4109
|
|
|
4106
4110
|
# Get save file name
|
|
4107
4111
|
file_filter = ("CSV Files (*.csv)" if file_type == 'csv' else
|
|
4108
|
-
"Excel Files (*.xlsx)" if file_type == '
|
|
4112
|
+
"Excel Files (*.xlsx)" if file_type == 'xlsx' else
|
|
4109
4113
|
"Gephi Graph (*.gexf)" if file_type == 'gexf' else
|
|
4110
4114
|
"GraphML (*.graphml)" if file_type == 'graphml' else
|
|
4111
4115
|
"Pajek Network (*.net)")
|
|
@@ -4490,7 +4494,13 @@ class TabbedDataWidget(QTabWidget):
|
|
|
4490
4494
|
"""Add a new table with the given name"""
|
|
4491
4495
|
if name in self.tables:
|
|
4492
4496
|
# If tab already exists, update its content
|
|
4493
|
-
|
|
4497
|
+
old_table = self.tables[name]
|
|
4498
|
+
idx = self.indexOf(old_table)
|
|
4499
|
+
|
|
4500
|
+
# Remove the old table reference from parent's data_table
|
|
4501
|
+
if self.parent_window and old_table in self.parent_window.data_table:
|
|
4502
|
+
self.parent_window.data_table.remove(old_table)
|
|
4503
|
+
|
|
4494
4504
|
self.removeTab(idx)
|
|
4495
4505
|
|
|
4496
4506
|
# Create a new CustomTableView with is_top_table=True
|
|
@@ -4510,7 +4520,7 @@ class TabbedDataWidget(QTabWidget):
|
|
|
4510
4520
|
|
|
4511
4521
|
# Update parent's data_table reference
|
|
4512
4522
|
if self.parent_window:
|
|
4513
|
-
self.parent_window.data_table
|
|
4523
|
+
self.parent_window.data_table.append(new_table)
|
|
4514
4524
|
|
|
4515
4525
|
def close_tab(self, index):
|
|
4516
4526
|
"""Close the tab at the given index"""
|
|
@@ -4525,12 +4535,12 @@ class TabbedDataWidget(QTabWidget):
|
|
|
4525
4535
|
if name_to_remove:
|
|
4526
4536
|
del self.tables[name_to_remove]
|
|
4527
4537
|
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
if self.parent_window and self.count() > 0:
|
|
4532
|
-
self.parent_window.data_table = self.currentWidget()
|
|
4538
|
+
# Update parent's data_table reference by removing the widget
|
|
4539
|
+
if self.parent_window and widget in self.parent_window.data_table:
|
|
4540
|
+
self.parent_window.data_table.remove(widget)
|
|
4533
4541
|
|
|
4542
|
+
self.removeTab(index)
|
|
4543
|
+
|
|
4534
4544
|
def clear_all_tabs(self):
|
|
4535
4545
|
"""Remove all tabs"""
|
|
4536
4546
|
while self.count() > 0:
|
|
@@ -5433,18 +5443,23 @@ class RadialDialog(QDialog):
|
|
|
5433
5443
|
|
|
5434
5444
|
def radial(self):
|
|
5435
5445
|
|
|
5436
|
-
|
|
5446
|
+
try:
|
|
5437
5447
|
|
|
5438
|
-
|
|
5448
|
+
distance = float(self.distance.text()) if self.distance.text().strip() else 50
|
|
5439
5449
|
|
|
5440
|
-
|
|
5441
|
-
self.parent().show_centroid_dialog()
|
|
5450
|
+
directory = str(self.distance.text()) if self.directory.text().strip() else None
|
|
5442
5451
|
|
|
5443
|
-
|
|
5452
|
+
if my_network.node_centroids is None:
|
|
5453
|
+
self.parent().show_centroid_dialog()
|
|
5444
5454
|
|
|
5445
|
-
|
|
5455
|
+
radial = my_network.radial_distribution(distance, directory = directory)
|
|
5446
5456
|
|
|
5447
|
-
|
|
5457
|
+
self.parent().format_for_upperright_table(radial, 'Radial Distance From Any Node', 'Average Number of Neighboring Nodes', title = 'Radial Distribution Analysis')
|
|
5458
|
+
|
|
5459
|
+
self.accept()
|
|
5460
|
+
|
|
5461
|
+
except Exception as e:
|
|
5462
|
+
print(f"An error occurred: {e}")
|
|
5448
5463
|
|
|
5449
5464
|
class DegreeDistDialog(QDialog):
|
|
5450
5465
|
|
|
@@ -5477,7 +5492,7 @@ class DegreeDistDialog(QDialog):
|
|
|
5477
5492
|
|
|
5478
5493
|
self.accept()
|
|
5479
5494
|
|
|
5480
|
-
except
|
|
5495
|
+
except Exception as e:
|
|
5481
5496
|
print(f"An error occurred: {e}")
|
|
5482
5497
|
|
|
5483
5498
|
class NeighborIdentityDialog(QDialog):
|
|
@@ -7783,6 +7798,12 @@ class SkeletonizeDialog(QDialog):
|
|
|
7783
7798
|
self.remove = QLineEdit("0")
|
|
7784
7799
|
layout.addRow("Remove Branches Pixel Length (int):", self.remove)
|
|
7785
7800
|
|
|
7801
|
+
# auto checkbox (default True)
|
|
7802
|
+
self.auto = QPushButton("Auto")
|
|
7803
|
+
self.auto.setCheckable(True)
|
|
7804
|
+
self.auto.setChecked(False)
|
|
7805
|
+
layout.addRow("Attempt to Auto Correct Skeleton Looping:", self.auto)
|
|
7806
|
+
|
|
7786
7807
|
# Add Run button
|
|
7787
7808
|
run_button = QPushButton("Run Skeletonize")
|
|
7788
7809
|
run_button.clicked.connect(self.run_skeletonize)
|
|
@@ -7796,11 +7817,17 @@ class SkeletonizeDialog(QDialog):
|
|
|
7796
7817
|
remove = int(self.remove.text()) if self.remove.text() else 0
|
|
7797
7818
|
except ValueError:
|
|
7798
7819
|
remove = 0
|
|
7820
|
+
|
|
7821
|
+
auto = self.auto.isChecked()
|
|
7799
7822
|
|
|
7800
7823
|
# Get the active channel data from parent
|
|
7801
7824
|
active_data = self.parent().channel_data[self.parent().active_channel]
|
|
7802
7825
|
if active_data is None:
|
|
7803
7826
|
raise ValueError("No active image selected")
|
|
7827
|
+
|
|
7828
|
+
if auto:
|
|
7829
|
+
active_data = n3d.skeletonize(active_data)
|
|
7830
|
+
active_data = n3d.fill_holes_3d(active_data)
|
|
7804
7831
|
|
|
7805
7832
|
# Call dilate method with parameters
|
|
7806
7833
|
result = n3d.skeletonize(
|
|
@@ -8112,11 +8139,17 @@ class GenNodesDialog(QDialog):
|
|
|
8112
8139
|
self.branch_removal = QLineEdit("0")
|
|
8113
8140
|
layout.addRow("Skeleton Voxel Branch Length to Remove (int) (Compensates for spines off medial axis):", self.branch_removal)
|
|
8114
8141
|
|
|
8142
|
+
self.comp_dil = QLineEdit("0")
|
|
8143
|
+
layout.addRow("Voxel distance to merge nearby nodes (Int - compensates for multi-branch identification along thick branch regions):", self.comp_dil)
|
|
8144
|
+
|
|
8115
8145
|
self.max_vol = QLineEdit("0")
|
|
8116
8146
|
layout.addRow("Maximum Voxel Volume of Vertices to Retain (int - Compensates for skeleton looping - occurs before any node merging - the smallest objects are always 27 voxels):", self.max_vol)
|
|
8117
8147
|
|
|
8118
|
-
|
|
8119
|
-
|
|
8148
|
+
# auto checkbox (default True)
|
|
8149
|
+
self.auto = QPushButton("Auto")
|
|
8150
|
+
self.auto.setCheckable(True)
|
|
8151
|
+
self.auto.setChecked(False)
|
|
8152
|
+
layout.addRow("Attempt to Auto Correct Skeleton Looping:", self.auto)
|
|
8120
8153
|
|
|
8121
8154
|
if not down_factor:
|
|
8122
8155
|
down_factor = None
|
|
@@ -8194,6 +8227,13 @@ class GenNodesDialog(QDialog):
|
|
|
8194
8227
|
else:
|
|
8195
8228
|
order = 0
|
|
8196
8229
|
|
|
8230
|
+
auto = self.auto.isChecked()
|
|
8231
|
+
|
|
8232
|
+
|
|
8233
|
+
if auto:
|
|
8234
|
+
my_network.edges = n3d.skeletonize(my_network.edges)
|
|
8235
|
+
my_network.edges = n3d.fill_holes_3d(my_network.edges)
|
|
8236
|
+
|
|
8197
8237
|
|
|
8198
8238
|
result, skele = n3d.label_vertices(
|
|
8199
8239
|
my_network.edges,
|
|
@@ -8248,6 +8288,7 @@ class GenNodesDialog(QDialog):
|
|
|
8248
8288
|
)
|
|
8249
8289
|
|
|
8250
8290
|
|
|
8291
|
+
|
|
8251
8292
|
class BranchDialog(QDialog):
|
|
8252
8293
|
|
|
8253
8294
|
def __init__(self, parent=None):
|
|
@@ -8275,8 +8316,7 @@ class BranchDialog(QDialog):
|
|
|
8275
8316
|
self.fix.setChecked(False)
|
|
8276
8317
|
layout.addRow("Attempt to auto-correct branch labels:", self.fix)
|
|
8277
8318
|
|
|
8278
|
-
self.fix_val = QLineEdit()
|
|
8279
|
-
self.fix_val.setPlaceholderText("Empty = default value...")
|
|
8319
|
+
self.fix_val = QLineEdit('4')
|
|
8280
8320
|
layout.addRow("If checked above - Avg Degree of Nearby Branch Communities to Merge (Attempt to fix branch labeling - try 4 to 6 to start or leave empty):", self.fix_val)
|
|
8281
8321
|
|
|
8282
8322
|
self.down_factor = QLineEdit("0")
|
nettracer3d/network_analysis.py
CHANGED
|
@@ -1024,11 +1024,8 @@ def histogram(counts, y_vals, directory = None):
|
|
|
1024
1024
|
plt.ylabel('Avg Number of Neigbhoring Vertices')
|
|
1025
1025
|
|
|
1026
1026
|
try:
|
|
1027
|
-
|
|
1028
1027
|
if directory is not None:
|
|
1029
1028
|
plt.savefig(f'{directory}/radial_plot.png')
|
|
1030
|
-
else:
|
|
1031
|
-
plt.savefig('radial_plot.png')
|
|
1032
1029
|
except:
|
|
1033
1030
|
pass
|
|
1034
1031
|
|
|
@@ -1439,6 +1436,7 @@ def degree_distribution(G, directory = None):
|
|
|
1439
1436
|
|
|
1440
1437
|
def power_trendline(x, y, directory = None):
|
|
1441
1438
|
# Handle zeros in y for logarithmic transformations
|
|
1439
|
+
"""
|
|
1442
1440
|
y = np.array(y)
|
|
1443
1441
|
x = np.array(x)
|
|
1444
1442
|
y[y == 0] += 0.001
|
|
@@ -1460,6 +1458,8 @@ def power_trendline(x, y, directory = None):
|
|
|
1460
1458
|
ss_res = np.sum((y - y_pred) ** 2)
|
|
1461
1459
|
ss_tot = np.sum((y - np.mean(y)) ** 2)
|
|
1462
1460
|
r2 = 1 - (ss_res / ss_tot)
|
|
1461
|
+
"""
|
|
1462
|
+
# ^ I commented out this power trendline stuff because I decided I no longer want it to do that so.
|
|
1463
1463
|
|
|
1464
1464
|
# Create a scatterplot
|
|
1465
1465
|
plt.scatter(x, y, label='Data')
|
|
@@ -1468,9 +1468,10 @@ def power_trendline(x, y, directory = None):
|
|
|
1468
1468
|
plt.title('Degree Distribution of Network')
|
|
1469
1469
|
|
|
1470
1470
|
# Plot the power trendline
|
|
1471
|
-
plt.plot(x_fit, y_fit, color='red', label=f'Power Trendline: $y = {a:.2f}x^{{{b:.2f}}}$')
|
|
1471
|
+
#plt.plot(x_fit, y_fit, color='red', label=f'Power Trendline: $y = {a:.2f}x^{{{b:.2f}}}$')
|
|
1472
1472
|
|
|
1473
1473
|
# Annotate the plot with the trendline equation and R-squared value
|
|
1474
|
+
"""
|
|
1474
1475
|
plt.text(
|
|
1475
1476
|
0.05, 0.95,
|
|
1476
1477
|
f'$y = {a:.2f}x^{{{b:.2f}}}$\n$R^2 = {r2:.2f}$',
|
|
@@ -1478,13 +1479,12 @@ def power_trendline(x, y, directory = None):
|
|
|
1478
1479
|
fontsize=12,
|
|
1479
1480
|
verticalalignment='top'
|
|
1480
1481
|
)
|
|
1482
|
+
"""
|
|
1481
1483
|
|
|
1482
1484
|
try:
|
|
1483
1485
|
|
|
1484
1486
|
if directory is not None:
|
|
1485
1487
|
plt.savefig(f'{directory}/degree_plot.png')
|
|
1486
|
-
else:
|
|
1487
|
-
plt.savefig('degree_plot.png')
|
|
1488
1488
|
except:
|
|
1489
1489
|
pass
|
|
1490
1490
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nettracer3d
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.4
|
|
4
4
|
Summary: Scripts for intializing and analyzing networks from segmentations of three dimensional images.
|
|
5
5
|
Author-email: Liam McLaughlin <mclaughlinliam99@gmail.com>
|
|
6
6
|
Project-URL: User_Tutorial, https://www.youtube.com/watch?v=cRatn5VTWDY
|
|
@@ -45,10 +45,15 @@ NetTracer3D is free to use/fork for academic/nonprofit use so long as citation i
|
|
|
45
45
|
|
|
46
46
|
NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
|
|
47
47
|
|
|
48
|
-
-- Version 0.6.
|
|
48
|
+
-- Version 0.6.4 updates --
|
|
49
49
|
|
|
50
|
-
1. Fixed bug with
|
|
50
|
+
1. Fixed bug with tabulated data in top right having a right click window corresponding to the bottom left.
|
|
51
51
|
|
|
52
|
-
2.
|
|
52
|
+
2. Fixed bug when converting communities to nodes that let the same community connect to itself in the new network.
|
|
53
53
|
|
|
54
|
-
3.
|
|
54
|
+
3. Removed attempted trendline fitting from degree distribution
|
|
55
|
+
|
|
56
|
+
4. Added new feature to skeletonization (and corresponding branch labeler/gennodes)
|
|
57
|
+
Now you can have the program attempt to auto-correct 3D skeletonization loop artifacts through a method that just runs the 3d fill holes algo and then attempts to reskeletonize the output. This worked well in my own testing.
|
|
58
|
+
|
|
59
|
+
5. Other minor fixes/improvements
|
|
@@ -2,9 +2,9 @@ nettracer3d/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
2
2
|
nettracer3d/community_extractor.py,sha256=Zq8ZM595CTzeR6zLEZ4I6KvhkNfCPUReWvAKxTlaVfk,33495
|
|
3
3
|
nettracer3d/modularity.py,sha256=V1f3s_vGd8EuVz27mzq6ycIGr0BWIpH7c7NU4QjgAHU,30247
|
|
4
4
|
nettracer3d/morphology.py,sha256=yQ0GuieMVXOQpaohZlPnkEXEuCUjf8Fg352axyK8nbM,10755
|
|
5
|
-
nettracer3d/nettracer.py,sha256=
|
|
6
|
-
nettracer3d/nettracer_gui.py,sha256=
|
|
7
|
-
nettracer3d/network_analysis.py,sha256=
|
|
5
|
+
nettracer3d/nettracer.py,sha256=FRNmyFJM38k0sIY4yJJfgMUfSQ57E_2VQ6QWk08vFV0,208721
|
|
6
|
+
nettracer3d/nettracer_gui.py,sha256=tpNQha14Z1NbSb359qgvNOtvTH1mwkChdRGw0TGQG7A,384945
|
|
7
|
+
nettracer3d/network_analysis.py,sha256=q1q7lxtA3lebxitfC_jfiT9cnpYXJw4q0Oy2_-Aj8qE,48068
|
|
8
8
|
nettracer3d/network_draw.py,sha256=F7fw6Pcf4qWOhdKwLmhwqWdschbDlHzwCVolQC9imeU,14117
|
|
9
9
|
nettracer3d/node_draw.py,sha256=k3sCTfUCJs3aH1C1q1gTNxDz9EAQbBd1hsUIJajxRx8,9823
|
|
10
10
|
nettracer3d/proximity.py,sha256=FnIiI_AzfXd22HwCIFIyQRZxKYJ8YscIDdPnIv-wsO4,10560
|
|
@@ -12,9 +12,9 @@ nettracer3d/run.py,sha256=xYeaAc8FCx8MuzTGyL3NR3mK7WZzffAYAH23bNRZYO4,127
|
|
|
12
12
|
nettracer3d/segmenter.py,sha256=oKQEKQpo3o6cqfN6Z_IAgx8V-HXpegQNjfWFz3Bdu04,83449
|
|
13
13
|
nettracer3d/simple_network.py,sha256=fP1gkDdtQcHruEZpUdasKdZeVacoLOxKhR3bY0L1CAQ,15426
|
|
14
14
|
nettracer3d/smart_dilate.py,sha256=6m03KHtRMv0zfJ2aHc1Om4Fhh2abPy-IqDzRCmIEHCY,24588
|
|
15
|
-
nettracer3d-0.6.
|
|
16
|
-
nettracer3d-0.6.
|
|
17
|
-
nettracer3d-0.6.
|
|
18
|
-
nettracer3d-0.6.
|
|
19
|
-
nettracer3d-0.6.
|
|
20
|
-
nettracer3d-0.6.
|
|
15
|
+
nettracer3d-0.6.4.dist-info/licenses/LICENSE,sha256=gM207DhJjWrxLuEWXl0Qz5ISbtWDmADfjHp3yC2XISs,888
|
|
16
|
+
nettracer3d-0.6.4.dist-info/METADATA,sha256=noTR2x1vIJVQ6a3pkNbbD2kLsZGPaFvq7QG4gZuehJE,3646
|
|
17
|
+
nettracer3d-0.6.4.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
18
|
+
nettracer3d-0.6.4.dist-info/entry_points.txt,sha256=Nx1rr_0QhJXDBHAQg2vcqCzLMKBzSHfwy3xwGkueVyc,53
|
|
19
|
+
nettracer3d-0.6.4.dist-info/top_level.txt,sha256=zsYy9rZwirfCEOubolhee4TyzqBAL5gSUeFMzhFTX8c,12
|
|
20
|
+
nettracer3d-0.6.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|