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.

Files changed (30) hide show
  1. {nettracer3d-0.9.8/src/nettracer3d.egg-info → nettracer3d-0.9.9}/PKG-INFO +4 -3
  2. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/README.md +3 -2
  3. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/pyproject.toml +1 -1
  4. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/nettracer_gui.py +141 -3
  5. {nettracer3d-0.9.8 → nettracer3d-0.9.9/src/nettracer3d.egg-info}/PKG-INFO +4 -3
  6. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/LICENSE +0 -0
  7. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/setup.cfg +0 -0
  8. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/__init__.py +0 -0
  9. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/cellpose_manager.py +0 -0
  10. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/community_extractor.py +0 -0
  11. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/excelotron.py +0 -0
  12. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/modularity.py +0 -0
  13. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/morphology.py +0 -0
  14. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/neighborhoods.py +0 -0
  15. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/nettracer.py +0 -0
  16. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/network_analysis.py +0 -0
  17. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/network_draw.py +0 -0
  18. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/node_draw.py +0 -0
  19. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/painting.py +0 -0
  20. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/proximity.py +0 -0
  21. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/run.py +0 -0
  22. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/segmenter.py +0 -0
  23. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/segmenter_GPU.py +0 -0
  24. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/simple_network.py +0 -0
  25. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d/smart_dilate.py +0 -0
  26. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d.egg-info/SOURCES.txt +0 -0
  27. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d.egg-info/dependency_links.txt +0 -0
  28. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d.egg-info/entry_points.txt +0 -0
  29. {nettracer3d-0.9.8 → nettracer3d-0.9.9}/src/nettracer3d.egg-info/requires.txt +0 -0
  30. {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.8
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.8 Updates --
113
+ -- Version 0.9.9 Updates --
114
114
 
115
- * Some minor bug fixes
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.8 Updates --
68
+ -- Version 0.9.9 Updates --
69
69
 
70
- * Some minor bug fixes
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.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "nettracer3d"
3
- version = "0.9.8"
3
+ version = "0.9.9"
4
4
  authors = [
5
5
  { name="Liam McLaughlin", email="liamm@wustl.edu" },
6
6
  ]
@@ -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 in self.parent.data_table: # Top table
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.8
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.8 Updates --
113
+ -- Version 0.9.9 Updates --
114
114
 
115
- * Some minor bug fixes
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