nettracer3d 0.9.8__tar.gz → 0.9.9__tar.gz
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-0.9.8/src/nettracer3d.egg-info → nettracer3d-0.9.9}/PKG-INFO +4 -3
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/README.md +3 -2
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/pyproject.toml +1 -1
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/nettracer_gui.py +141 -3
- {nettracer3d-0.9.8 → nettracer3d-0.9.9/src/nettracer3d.egg-info}/PKG-INFO +4 -3
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/LICENSE +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/setup.cfg +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/__init__.py +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/cellpose_manager.py +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/community_extractor.py +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/excelotron.py +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/modularity.py +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/morphology.py +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/neighborhoods.py +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/nettracer.py +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/network_analysis.py +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/network_draw.py +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/node_draw.py +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/painting.py +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/proximity.py +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/run.py +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/segmenter.py +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/segmenter_GPU.py +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/simple_network.py +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/smart_dilate.py +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d.egg-info/SOURCES.txt +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d.egg-info/dependency_links.txt +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d.egg-info/entry_points.txt +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d.egg-info/requires.txt +0 -0
- {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nettracer3d
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.9
|
|
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/
|
|
@@ -110,6 +110,7 @@ McLaughlin, L., Zhang, B., Sharma, S. et al. Three dimensional multiscalar neuro
|
|
|
110
110
|
|
|
111
111
|
NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
|
|
112
112
|
|
|
113
|
-
-- Version 0.9.
|
|
113
|
+
-- Version 0.9.9 Updates --
|
|
114
114
|
|
|
115
|
-
*
|
|
115
|
+
* Tables can now be opened to the rightside upper widget if they are the right format.
|
|
116
|
+
* Similarly, tables that have the format node id column:numerical values can now be used liberally to threshold the nodes, meaning most outputs of network analysis can be used to threshold nodes.
|
|
@@ -65,6 +65,7 @@ McLaughlin, L., Zhang, B., Sharma, S. et al. Three dimensional multiscalar neuro
|
|
|
65
65
|
|
|
66
66
|
NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
|
|
67
67
|
|
|
68
|
-
-- Version 0.9.
|
|
68
|
+
-- Version 0.9.9 Updates --
|
|
69
69
|
|
|
70
|
-
*
|
|
70
|
+
* Tables can now be opened to the rightside upper widget if they are the right format.
|
|
71
|
+
* Similarly, tables that have the format node id column:numerical values can now be used liberally to threshold the nodes, meaning most outputs of network analysis can be used to threshold nodes.
|
|
@@ -466,6 +466,102 @@ class ImageViewerWindow(QMainWindow):
|
|
|
466
466
|
self.hold_update = False
|
|
467
467
|
self._first_pan_done = False
|
|
468
468
|
|
|
469
|
+
|
|
470
|
+
def load_file(self):
|
|
471
|
+
"""Load CSV or Excel file and convert to dictionary format."""
|
|
472
|
+
try:
|
|
473
|
+
# Open file dialog
|
|
474
|
+
file_filter = "Spreadsheet Files (*.csv *.xlsx);;CSV Files (*.csv);;Excel Files (*.xlsx)"
|
|
475
|
+
filename, _ = QFileDialog.getOpenFileName(
|
|
476
|
+
self,
|
|
477
|
+
"Load File",
|
|
478
|
+
"",
|
|
479
|
+
file_filter
|
|
480
|
+
)
|
|
481
|
+
|
|
482
|
+
if not filename:
|
|
483
|
+
return
|
|
484
|
+
|
|
485
|
+
# Read the file
|
|
486
|
+
if filename.endswith('.csv'):
|
|
487
|
+
df = pd.read_csv(filename)
|
|
488
|
+
elif filename.endswith('.xlsx'):
|
|
489
|
+
df = pd.read_excel(filename)
|
|
490
|
+
else:
|
|
491
|
+
QMessageBox.warning(self, "Error", "Please select a CSV or Excel file.")
|
|
492
|
+
return
|
|
493
|
+
|
|
494
|
+
if df.empty:
|
|
495
|
+
QMessageBox.warning(self, "Error", "The file appears to be empty.")
|
|
496
|
+
return
|
|
497
|
+
|
|
498
|
+
# Extract headers
|
|
499
|
+
headers = df.columns.tolist()
|
|
500
|
+
if len(headers) < 1:
|
|
501
|
+
QMessageBox.warning(self, "Error", "File must have at least 1 column.")
|
|
502
|
+
return
|
|
503
|
+
|
|
504
|
+
# Extract filename without extension for title
|
|
505
|
+
import os
|
|
506
|
+
title = os.path.splitext(os.path.basename(filename))[0]
|
|
507
|
+
|
|
508
|
+
if len(headers) == 1:
|
|
509
|
+
# Single column: pass header to metric, column data as list to data, nothing to value
|
|
510
|
+
metric = headers[0]
|
|
511
|
+
data = df.iloc[:, 0].tolist() # First column as list
|
|
512
|
+
value = None
|
|
513
|
+
|
|
514
|
+
self.format_for_upperright_table(
|
|
515
|
+
data=data,
|
|
516
|
+
metric=metric,
|
|
517
|
+
value=value,
|
|
518
|
+
title=title
|
|
519
|
+
)
|
|
520
|
+
else:
|
|
521
|
+
# Multiple columns: create dictionary as before
|
|
522
|
+
# First column header (for metric parameter)
|
|
523
|
+
metric = headers[0]
|
|
524
|
+
|
|
525
|
+
# Remaining headers (for value parameter)
|
|
526
|
+
value = headers[1:]
|
|
527
|
+
|
|
528
|
+
# Create dictionary
|
|
529
|
+
data_dict = {}
|
|
530
|
+
|
|
531
|
+
for index, row in df.iterrows():
|
|
532
|
+
key = row.iloc[0] # First column value as key
|
|
533
|
+
|
|
534
|
+
if len(headers) == 2:
|
|
535
|
+
# If only 2 columns, store single value
|
|
536
|
+
data_dict[key] = row.iloc[1]
|
|
537
|
+
else:
|
|
538
|
+
# If more than 2 columns, store as list
|
|
539
|
+
data_dict[key] = row.iloc[1:].tolist()
|
|
540
|
+
|
|
541
|
+
if len(value) == 1:
|
|
542
|
+
value = value[0]
|
|
543
|
+
|
|
544
|
+
# Call the parent method
|
|
545
|
+
self.format_for_upperright_table(
|
|
546
|
+
data=data_dict,
|
|
547
|
+
metric=metric,
|
|
548
|
+
value=value,
|
|
549
|
+
title=title
|
|
550
|
+
)
|
|
551
|
+
|
|
552
|
+
QMessageBox.information(
|
|
553
|
+
self,
|
|
554
|
+
"Success",
|
|
555
|
+
f"File '{title}' loaded successfully with {len(df)} entries."
|
|
556
|
+
)
|
|
557
|
+
|
|
558
|
+
except Exception as e:
|
|
559
|
+
QMessageBox.critical(
|
|
560
|
+
self,
|
|
561
|
+
"Error",
|
|
562
|
+
f"Failed to load file: {str(e)}"
|
|
563
|
+
)
|
|
564
|
+
|
|
469
565
|
def popup_canvas(self):
|
|
470
566
|
"""Pop the canvas out into its own window"""
|
|
471
567
|
if hasattr(self, 'popup_window') and self.popup_window.isVisible():
|
|
@@ -4433,6 +4529,12 @@ class ImageViewerWindow(QMainWindow):
|
|
|
4433
4529
|
cam_button.setStyleSheet("font-size: 24px;")
|
|
4434
4530
|
cam_button.clicked.connect(self.snap)
|
|
4435
4531
|
corner_layout.addWidget(cam_button)
|
|
4532
|
+
|
|
4533
|
+
load_button = QPushButton("📁")
|
|
4534
|
+
load_button.setFixedSize(40, 40)
|
|
4535
|
+
load_button.setStyleSheet("font-size: 24px;")
|
|
4536
|
+
load_button.clicked.connect(self.load_file)
|
|
4537
|
+
corner_layout.addWidget(load_button)
|
|
4436
4538
|
|
|
4437
4539
|
# Set as corner widget
|
|
4438
4540
|
menubar.setCornerWidget(corner_widget, Qt.Corner.TopRightCorner)
|
|
@@ -6655,15 +6757,19 @@ class CustomTableView(QTableView):
|
|
|
6655
6757
|
desc_action.triggered.connect(lambda checked, c=col: self.sort_table(c, ascending=False))
|
|
6656
6758
|
|
|
6657
6759
|
# Different menus for top and bottom tables
|
|
6658
|
-
if self
|
|
6760
|
+
if self.is_top_table: # Use the flag instead of checking membership
|
|
6659
6761
|
save_menu = context_menu.addMenu("Save As")
|
|
6660
6762
|
save_csv = save_menu.addAction("CSV")
|
|
6661
6763
|
save_excel = save_menu.addAction("Excel")
|
|
6764
|
+
|
|
6765
|
+
if self.model() and len(self.model()._data.columns) == 2:
|
|
6766
|
+
thresh_action = context_menu.addAction("Use to Threshold Nodes")
|
|
6767
|
+
thresh_action.triggered.connect(lambda: self.thresh(self.create_threshold_dict()))
|
|
6768
|
+
|
|
6662
6769
|
close_action = context_menu.addAction("Close All")
|
|
6663
|
-
|
|
6664
6770
|
close_action.triggered.connect(self.close_all)
|
|
6665
6771
|
|
|
6666
|
-
# Connect the actions
|
|
6772
|
+
# Connect the save actions
|
|
6667
6773
|
save_csv.triggered.connect(lambda: self.save_table_as('csv'))
|
|
6668
6774
|
save_excel.triggered.connect(lambda: self.save_table_as('xlsx'))
|
|
6669
6775
|
else: # Bottom tables
|
|
@@ -6707,6 +6813,38 @@ class CustomTableView(QTableView):
|
|
|
6707
6813
|
cursor_pos = QCursor.pos()
|
|
6708
6814
|
context_menu.exec(cursor_pos)
|
|
6709
6815
|
|
|
6816
|
+
|
|
6817
|
+
|
|
6818
|
+
def thresh(self, special_dict):
|
|
6819
|
+
try:
|
|
6820
|
+
self.parent.special_dict = special_dict
|
|
6821
|
+
thresh_window = ThresholdWindow(self.parent, 4)
|
|
6822
|
+
thresh_window.show()
|
|
6823
|
+
except:
|
|
6824
|
+
pass
|
|
6825
|
+
|
|
6826
|
+
def create_threshold_dict(self):
|
|
6827
|
+
try:
|
|
6828
|
+
"""Create a dictionary from the 2-column table data."""
|
|
6829
|
+
if not self.model() or not hasattr(self.model(), '_data'):
|
|
6830
|
+
return {}
|
|
6831
|
+
|
|
6832
|
+
df = self.model()._data
|
|
6833
|
+
if len(df.columns) != 2:
|
|
6834
|
+
return {}
|
|
6835
|
+
|
|
6836
|
+
# Create dictionary: {column_0_value: column_1_value}
|
|
6837
|
+
threshold_dict = {}
|
|
6838
|
+
for index, row in df.iterrows():
|
|
6839
|
+
key = row.iloc[0] # Column 0 value
|
|
6840
|
+
value = row.iloc[1] # Column 1 value
|
|
6841
|
+
threshold_dict[int(key)] = float(value)
|
|
6842
|
+
|
|
6843
|
+
return threshold_dict
|
|
6844
|
+
except:
|
|
6845
|
+
pass
|
|
6846
|
+
|
|
6847
|
+
|
|
6710
6848
|
def sort_table(self, column, ascending=True):
|
|
6711
6849
|
"""Sort the table by the specified column."""
|
|
6712
6850
|
try:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nettracer3d
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.9
|
|
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/
|
|
@@ -110,6 +110,7 @@ McLaughlin, L., Zhang, B., Sharma, S. et al. Three dimensional multiscalar neuro
|
|
|
110
110
|
|
|
111
111
|
NetTracer3D was developed by Liam McLaughlin while working under Dr. Sanjay Jain at Washington University School of Medicine.
|
|
112
112
|
|
|
113
|
-
-- Version 0.9.
|
|
113
|
+
-- Version 0.9.9 Updates --
|
|
114
114
|
|
|
115
|
-
*
|
|
115
|
+
* Tables can now be opened to the rightside upper widget if they are the right format.
|
|
116
|
+
* Similarly, tables that have the format node id column:numerical values can now be used liberally to threshold the nodes, meaning most outputs of network analysis can be used to threshold nodes.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|