Skip to content

Commit

Permalink
Merge pull request #1259 from psavery/delete-grains
Browse files Browse the repository at this point in the history
Add ability to delete grains in some dialogs
  • Loading branch information
psavery authored Aug 25, 2022
2 parents a310b44 + a9ef8b9 commit 773ce1c
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 4 deletions.
8 changes: 8 additions & 0 deletions hexrd/ui/indexing/fit_grains_options_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
class FitGrainsOptionsDialog(QObject):
accepted = Signal()
rejected = Signal()
grains_table_modified = Signal()

def __init__(self, grains_table, parent=None):
super().__init__(parent)
Expand All @@ -44,6 +45,7 @@ def __init__(self, grains_table, parent=None):
view = self.ui.grains_table_view
view.data_model = self.data_model
view.material = self.material
view.can_modify_grains = True

ok_button = self.ui.button_box.button(QDialogButtonBox.Ok)
ok_button.setText('Fit Grains')
Expand Down Expand Up @@ -86,6 +88,8 @@ def setup_connections(self):
HexrdConfig().materials_dict_modified.connect(self.update_materials)

self.ui.plot_grains.clicked.connect(self.plot_grains)
self.data_model.grains_table_modified.connect(
self.on_grains_table_modified)

def all_widgets(self):
"""Only includes widgets directly related to config parameters"""
Expand Down Expand Up @@ -344,3 +348,7 @@ def set_working_dir(self):

def plot_grains(self):
plot_grains(self.grains_table, None, parent=self.ui)

def on_grains_table_modified(self):
self.grains_table = self.data_model.full_grains_table
self.grains_table_modified.emit()
17 changes: 15 additions & 2 deletions hexrd/ui/indexing/fit_grains_results_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ def __init__(self, data, material=None, parent=None):
self.load_cmaps()
self.reset_glyph_size(update_plot=False)

self.add_extra_data_columns()

self.setup_gui()

def add_extra_data_columns(self):
# Add columns for equivalent strain and hydrostatic strain
eqv_strain = np.zeros(self.num_grains)
hydrostatic_strain = np.zeros(self.num_grains)
Expand All @@ -82,8 +87,6 @@ def __init__(self, data, material=None, parent=None):
self.data = np.hstack((self.data, eqv_strain[:, np.newaxis]))
self.data = np.hstack((self.data, hydrostatic_strain[:, np.newaxis]))

self.setup_gui()

def setup_gui(self):
self.update_selectors()
self.setup_plot()
Expand Down Expand Up @@ -313,6 +316,9 @@ def setup_connections(self):
self.ui.convert_strain_to_stress.toggled.connect(
self.convert_strain_to_stress_toggled)

self.data_model.grains_table_modified.connect(
self.on_grains_table_modified)

def setup_plot(self):
# Create the figure and axes to use
canvas = FigureCanvas(Figure(tight_layout=True))
Expand Down Expand Up @@ -465,6 +471,7 @@ def setup_tableview(self):
# Update the variables on the table view
view.data_model = self.data_model
view.material = self.material
view.can_modify_grains = True

def show(self):
self.ui.show()
Expand Down Expand Up @@ -571,6 +578,12 @@ def reset_glyph_size(self, update_plot=True):
def draw_idle(self):
self.canvas.draw_idle()

def on_grains_table_modified(self):
# Update our grains table
self.data = self.data_model.full_grains_table
self.add_extra_data_columns()
self.update_plot()


if __name__ == '__main__':
from PySide2.QtCore import QCoreApplication
Expand Down
46 changes: 45 additions & 1 deletion hexrd/ui/indexing/grains_table_model.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import numpy as np

from PySide2.QtCore import QAbstractTableModel, QModelIndex, Qt
from PySide2.QtCore import QAbstractTableModel, QModelIndex, Qt, Signal


class GrainsTableModel(QAbstractTableModel):
"""Model for viewing grains"""

grains_table_modified = Signal()

def __init__(self, grains_table, excluded_columns=None, parent=None):
super().__init__(parent)
self.full_grains_table = grains_table
Expand All @@ -23,6 +25,9 @@ def __init__(self, grains_table, excluded_columns=None, parent=None):

self.excluded_columns = excluded_columns if excluded_columns else []

self.regenerate_grains_table()

def regenerate_grains_table(self):
self.grains_table = self.full_grains_table[:, self.included_columns]
self.headers = [self.full_headers[x] for x in self.included_columns]

Expand Down Expand Up @@ -51,8 +56,47 @@ def rowCount(self, parent=QModelIndex()):

return len(self.grains_table)

def removeRows(self, row, count, parent):
while count > 0:
self.full_grains_table = np.delete(self.full_grains_table, row,
axis=0)
count -= 1

self.regenerate_grains_table()

return True

# Custom methods

def delete_grains(self, grain_ids):
any_modified = False
for grain_id in grain_ids:
to_delete = np.where(self.full_grains_table[:, 0] == grain_id)[0]
if to_delete.size == 0:
continue

self.remove_rows(to_delete)
any_modified = True

if any_modified:
self.renumber_grains()
self.grains_table_modified.emit()

def renumber_grains(self):
sorted_indices = np.argsort(self.full_grains_table[:, 0])
print(f'Renumbering grains from 0 to {len(sorted_indices) - 1}...')

for i, ind in enumerate(sorted_indices):
self.full_grains_table[ind, 0] = i

self.regenerate_grains_table()

def remove_rows(self, rows):
for row in rows:
self.beginRemoveRows(QModelIndex(), row, row)
self.removeRow(row)
self.endRemoveRows()

@property
def included_columns(self):
return [i for i in range(len(self.full_headers))
Expand Down
25 changes: 24 additions & 1 deletion hexrd/ui/indexing/grains_table_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from PySide2.QtCore import QSortFilterProxyModel, Qt, Signal
from PySide2.QtGui import QCursor
from PySide2.QtWidgets import QMenu, QTableView
from PySide2.QtWidgets import QMenu, QMessageBox, QTableView

from hexrd.ui.async_runner import AsyncRunner
from hexrd.ui.hexrd_config import HexrdConfig
Expand All @@ -27,6 +27,7 @@ def __init__(self, parent=None):

self.material = None
self.pull_spots_allowed = True
self.can_modify_grains = False
self._data_model = None
self._tolerances = []
self.selected_tol_id = -1
Expand All @@ -47,6 +48,10 @@ def add_actions(d):
if self.can_run_pull_spots:
add_actions({'Visualize Spots': self.pull_spots})

if self.can_modify_grains and self.num_selected_grains > 0:
suffix = 's' if self.num_selected_grains > 1 else ''
add_actions({f'Delete Grain{suffix}': self.delete_selected_grains})

if not actions:
return super().contextMenuEvent(event)

Expand Down Expand Up @@ -98,6 +103,10 @@ def selected_grains(self):

return self.grains_table[grain_ids]

@property
def num_selected_grains(self):
return len(self.selected_grain_ids)

@property
def can_run_pull_spots(self):
return (
Expand Down Expand Up @@ -127,6 +136,10 @@ def tolerances(self):
def tolerances(self, v):
self._tolerances = v

@property
def num_grains(self):
return len(self.data_model.grains_table)

def select_tolerance_id(self):
tolerances = self.tolerances
if len(tolerances) == 1:
Expand All @@ -150,6 +163,16 @@ def select_tolerance_id(self):
self.selected_tol_id = dialog.selected_row
return True

def delete_selected_grains(self):
if self.num_selected_grains == self.num_grains:
# Don't let the user delete all of the grains
msg = 'Cannot delete all grains'
print(msg)
QMessageBox.critical(self, 'HEXRD', msg)
return

self.data_model.delete_grains(self.selected_grain_ids)

def pull_spots(self):
if not self.select_tolerance_id():
# User canceled
Expand Down
6 changes: 6 additions & 0 deletions hexrd/ui/indexing/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,12 @@ def view_fit_grains_options(self):
dialog = FitGrainsOptionsDialog(self.grains_table, self.parent)
dialog.accepted.connect(self.fit_grains_options_accepted)
dialog.rejected.connect(self.clear)

def on_grains_table_modified():
# Update our grains table
self.grains_table = dialog.grains_table

dialog.grains_table_modified.connect(on_grains_table_modified)
self.fit_grains_options_dialog = dialog
dialog.show()

Expand Down

0 comments on commit 773ce1c

Please sign in to comment.