Unverified Commit e829d212 authored by Whitfield, Ross's avatar Whitfield, Ross Committed by GitHub
Browse files

Add ability to add and remove peaks from SliceViewer (#31678)



* type hints and actions package

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* forward declarations to prevent import loops

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* forward declarations to prevent import loops

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* Add buttons and combo box

* Update function name

* subscribing the presenter to the viewer

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* Modify grid layout

* Include correct import

* Add actions.ui file

* Tying the PeaksActionModel to the presenter

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* Instantiating the peak actions

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* group box in ui file

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* append/remove PeaksWorkspace from the view

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* resolve circular imports

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* lazy connections between vier and presenter

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* getattr should've been hasattr

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* getattr should've been hasattr

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* route signals only when presenter is not None

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* Hack to get everything showing, need to fix PeakAction size policy

* Get remove_peaks working

* Add a peak to the workspace

* Ugly but have peak adding working

* Add minimum size to PeakActionsView

* Move coordinate transform to sliceview presenter

* Move add_peak from PeakAction model to PeaksViewer model

* Trigger ADS update when adding peaks from python

* Check one button at a time

* Disable pan and zoom while adding peaks

* Add minimum width for actions widget

* Force draw after workspace replaced

* Deactivate peak adding if pan or zoom selected

* Remove handle PeakActionsPresenter from PeaksViewerCollectionView

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* rename peaks_actions_view property

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* Revert "rename peaks_actions_view property"

This reverts commit 0b59766b.

* Revert "Remove handle PeakActionsPresenter from PeaksViewerCollectionView"

This reverts commit c3eeb15b

.

* PeakActionsPresenter not used in PeaksViewerCollectionView

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* Remove actions presenter and view

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* move actions/view.py to peaksviewers/

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* Cleanup peak adding

* Change 'button_press_event' connection

* Fix button selections

* Add tests for adding peaks in peaksviewer

* Add test for sliceviewer.presenter/peak_add_delete

* peak deletion deletes peak closest to input position

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* Unify deleting/adding peaks

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* test delete peaks

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* Don't need to include frame from sliceviewer, PeaksViewer knows this

* Change SliceViewer.peak_add_delete to add_delete_peak to make it the same as PeaksViewerCollectionPresenter

Also simplify PeaksViewerModel.delete_peak

* Add peaksviewer/sliceviewer integration test for add/remove peaks

* send AfterReplaceNotification after removal of a peak

Signed-off-by: default avatarJose Borreguero <borreguero@gmail.com>

* Fix coordinate transform

* Make PeaksViewerModel.delete_peak faster

* Fix test_peak_add_delete_event

* Fix workspace ordering with multiple peaks workspaces

And cleanup some unused methods.

* Add test for PeakActionView.set_peaksworkspace

* Update docs

* Change replace/rename handle to keep same position

* Adjust test for changes to replace/rename handle

* Set visibility specs

* Update docs

* Forgot to add new image

* Fix two issue with peak overlay display,

Should be checking all workspaces instead of just newly added workspaces. Deactivate peak adding/removing when peak overlay is closed

Co-authored-by: default avatarJose Borreguero <borreguero@gmail.com>
Co-authored-by: default avatarJenna Delozier <jennakate998@gmail.com>
Co-authored-by: default avatarJenna DeLozier <52164248+jenest@users.noreply.github.com>
parent ca31644c
......@@ -60,11 +60,21 @@ IPeak *createPeakQSample(IPeaksWorkspace &self, const object &data) {
}
/// Create a peak via it's QLab value from a list or numpy array
void addPeak(IPeaksWorkspace &self, const IPeak &peak) { self.addPeak(peak); }
void addPeak(IPeaksWorkspace &self, const IPeak &peak) {
self.addPeak(peak);
self.modified();
}
/// Add a peak with its Q-vector (using a list of numpy array) and the coordinate frm (Qlab, Qsmaple, HKL)
void addPeak2(IPeaksWorkspace &self, const object &data, const SpecialCoordinateSystem &frame) {
self.addPeak(PyObjectToV3D(data)(), frame);
self.modified();
}
/// Remove a peak and send an AfterReplaceNotification for subscribed viewers, such as sliceviewer's
void removePeak(IPeaksWorkspace &self, int peak_num) {
self.removePeak(peak_num);
self.modified();
}
/**
......@@ -246,8 +256,7 @@ void export_IPeaksWorkspace() {
"Returns the number of peaks within the workspace")
.def("addPeak", addPeak, (arg("self"), arg("peak")), "Add a peak to the workspace")
.def("addPeak", addPeak2, (arg("self"), arg("data"), arg("coord_system")), "Add a peak to the workspace")
.def("removePeak", &IPeaksWorkspace::removePeak, (arg("self"), arg("peak_num")),
"Remove a peak from the workspace")
.def("removePeak", removePeak, (arg("self"), arg("peak_num")), "Remove a peak from the workspace")
.def("getPeak", &IPeaksWorkspace::getPeakPtr, (arg("self"), arg("peak_num")), return_internal_reference<>(),
"Returns a peak at the given index")
.def("createPeak", createPeakQLab, (arg("self"), arg("data")), return_value_policy<manage_new_object>(),
......
......@@ -116,7 +116,7 @@ Viewing a LeanElasticPeaksWorkspace
-----------------------------------
* Double-click a LeanElasticPeaksWorkspace to see the full list of data of each Peak object.
* The LeanElasticPeaksWorkspace can be overlay onto of data using the Mantid Workbench Sliceviewer
* The LeanElasticPeaksWorkspace can be overlay onto of data using :ref:`sliceviewer`.
The LeanElasticPeak Object
--------------------------
......
......@@ -8,7 +8,9 @@ Mantid Workbench Changes
New and Improved
----------------
- Peaks can now be added or removed from a PeaksWorkspace using the :ref:`peaks overlay <sliceviewer_peaks_overlay>` in :ref:`sliceviewer`.
Bugfixes
--------
:ref:`Release 6.2.0 <v6.2.0>`
\ No newline at end of file
:ref:`Release 6.2.0 <v6.2.0>`
......@@ -33,6 +33,25 @@ The following sections illustrate some of these key features.
PeaksWorkspace Overlay
----------------------
.. the following figure are generated by running the following:
SXD23767 = Load(Filename='SXD23767.raw', LoadMonitors='Exclude')
peaksws = Load('peaks_qLab.nxs')
FindUBUsingFFT(PeaksWorkspace='peaksws', MinD=0.8, MaxD=10)
IndexPeaks(peaksws, Tolerance=0.05)
CopySample(InputWorkspace='peaksws', OutputWorkspace='SXD23767',
CopyName=False, CopyMaterial=False, CopyEnvironment=False, CopyShape=False)
mdws = ConvertToDiffractionMDWorkspace(SXD23767,
OutputDimensions='HKL',
OneEventPerBin=False,
LorentzCorrection=True)
IntegratePeaksMD(InputWorkspace=mdws,
PeaksWorkspace=peaksws,
PeakRadius=0.2,
BackgroundInnerRadius=0.3,
BackgroundOuterRadius=0.35,
OutputWorkspace='mdws_integrated')
The peaks overlay button allows selection of one or more PeaksWorkspaces to display on top of the main data image.
This is only enabled for MD workspaces.
......@@ -44,11 +63,35 @@ Peaks are displayed at the locations defined by each peak center
with an 'x', while optionally displaying any peak shape if a given peak has
been integrated.
.. figure:: ../images/wb-sliceviewer51-peaksoverlay.png
.. figure:: ../images/wb-sliceviewer52-peaksoverlay.png
:class: screenshot
:width: 75%
:align: center
Adding or removing peaks
~~~~~~~~~~~~~~~~~~~~~~~~
Peaks can be added or removed from an overlayed peaks workspace by
selecting the desired peaks workspace from the drop down box (1) and
selecting either ``Add Peaks`` or ``Remove Peaks`` (2), then clicking
on the plot (3).
.. figure:: ../images/wb-sliceviewer52-peaks-actions.png
:class: screenshot
:width: 75%
:align: center
When adding peaks the position selected with the mouse click and the
sliders are used, along with the MD Frame (Q_lab, Q_sample, HKL) to
create and add a peak to the seleceted peaks workspace. If units are
HKL then the peaks workspace requires an orientated lattice to be
defined on it, one can be copied from the data workspace with
:ref:`CopySample <algm-CopySample>` or can be set with :ref:`SetUB
<algm-SetUB>`..
When removing peaks, the closest peak to the position selected will be
removed from the peaks workspace, regardless of whether it is plotted
or not.
Non-Orthogonal Axes View
------------------------
......@@ -134,4 +177,4 @@ and for an MDWorkspace:
Underneath the cursor there is a checkbox labelled ``Track Cursor``.
When checked, the information in the table is updated as the cursor moves
around the image. If unchecked, the information within the table is updated
only when the left-mouse button is clicked within the image.
\ No newline at end of file
only when the left-mouse button is clicked within the image.
......@@ -131,12 +131,14 @@ if(ENABLE_WORKBENCH)
mantidqt/widgets/sliceviewer/test/test_sliceviewer_transform.py
mantidqt/widgets/sliceviewer/test/test_sliceviewer_view.py
mantidqt/widgets/sliceviewer/test/test_sliceviewer_zoom.py
mantidqt/widgets/sliceviewer/peaksviewer/test/test_peaksviewer_actions.py
mantidqt/widgets/sliceviewer/peaksviewer/test/test_peaksviewer_model.py
mantidqt/widgets/sliceviewer/peaksviewer/test/test_peaksviewer_presenter.py
mantidqt/widgets/sliceviewer/peaksviewer/test/test_peaksviewer_view.py
mantidqt/widgets/sliceviewer/peaksviewer/test/test_peaksviewer_peaksviewercollectionpresenter.py
mantidqt/widgets/sliceviewer/peaksviewer/test/test_peaksviewer_peaksworkspaceselectormodel.py
mantidqt/widgets/sliceviewer/peaksviewer/test/test_peaksviewer_peaksworkspaceselectorpresenter.py
mantidqt/widgets/sliceviewer/peaksviewer/test/test_peaksviewer_sliceviewer_add_delete_peaks_integration.py
mantidqt/widgets/sliceviewer/peaksviewer/representation/test/test_peaksviewer_representation_alpha.py
mantidqt/widgets/sliceviewer/peaksviewer/representation/test/test_peaksviewer_representation_draw.py
mantidqt/widgets/sliceviewer/peaksviewer/representation/test/test_peaksviewer_representation_painter.py
......
@startuml
'https://plantuml.com/class-diagram
TableWorkspaceDataPresenterStandard -|> TableWorkspaceDataPresenterBase
PeaksViewerModel -|> TableWorkspaceDisplayModel
PeaksViewerModel --o TableWorkspaceDataPresenterBase
PeaksViewerPresenter *-- PeaksViewerModel
PeaksViewerPresenter *-- PeaksWorkspaceDataPresenter
PeaksWorkspaceDataPresenter -|> TableWorkspaceDataPresenterStandard
PeaksViewerView o--* PeaksViewerPresenter
PeaksViewerView o-- _PeaksWorkspaceTableView
_PeaksWorkspaceTableView --o TableWorkspaceDataPresenterBase
_LessThanOperatorSortFilterModel -|> QSortFilterModel
_PeaksWorkspaceTableView o-- _LessThanOperatorSortFilterModel
_PeaksWorkspaceTableView -|> TableWorkspaceDisplayView
SlicerView --o PeaksViewerView
TableWorkspaceDisplayView -|> QTableView
QTableView -|> QAbstractItemView
PeaksViewerCollectionView o-- SlicerView
PeaksViewerCollectionView *-- PeaksViewerView
PeaksViewerCollectionPresenter *-- PeaksViewerPresenter
PeaksViewerCollectionPresenter *-- PeaksViewerCollectionView
'mantidqt/widgets/workspacedisplay/table/model.py
class TableWorkspaceDisplayModel{
ITableWorkspace ws
delete_rows(selected_rows)
}
class TableWorkspaceDisplayView{
presenter = None
QStandardItemModel table_model
}
class QTableView
class QAbstractItemView
class TableWorkspaceDataPresenterStandard{
}
class TableWorkspaceDataPresenterBase{
PeaksViewerModel model
_PeaksWorkspaceTableView view
}
'slicerviewer.py'
class SlicerView {
}
'peaksviewer/model.py
class PeaksViewerModel{
Painted[] _representations
}
class _LessThanOperatorSortFilterModel{
less_than()
}
class QSortFilterModel{
}
'peaksviewer/view.py
class _PeaksWorkspaceTableView{
PeaksViewerView _key_handler
_LessThanOperatorSortFilterModel proxy_model
QAbstractItemModel source_model
}
class PeaksViewerView{
MPLPainter _painter
SliceViewer _slice_info_provider
QGroupBox _group_box
PeaksViewerPresenter _child_presenter
_PeaksWorkspaceTableView _table_view
}
class PeaksViewerCollectionView {
MPLPainter _painter
SlicerView _slice_info_provider
QVBoxLayout[PeaksViewerView] _peaks_layout
PeaksViewerView append_peaksviewer()
remove_peaksviewer(PeaksViewerView)
}
'peaksviewer/presenter.py
class PeaksWorkspaceDataPresenter{
create_items(Union[float, str] data)
}
class PeaksViewerPresenter{
PeaksViewerModel _model
PeaksViewerView _view
PeaksWorkspaceDataPresenter _peaks_table_presenter
}
class PeaksViewerCollectionPresenter {
PeaksViewerPresenter[] _child_presenters
PeaksViewerCollectionView _view
}
@enduml
\ No newline at end of file
# Mantid Repository : https://github.com/mantidproject/mantid
#
# Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
# NScD Oak Ridge National Laboratory, European Spallation Source,
# Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
# SPDX - License - Identifier: GPL - 3.0 +
# coding=utf-8
# This file is part of the mantidqt package.
# 3rd party
from qtpy import QtWidgets
from mantidqt.utils.qt import load_ui
# standard
from typing import Optional
class PeakActionsView(QtWidgets.QWidget):
def __init__(self, parent: Optional['PeaksViewerCollectionView'] = None):
super(PeakActionsView, self).__init__(parent=parent)
self._presenter: 'PeaksViewerCollectionPresenter' = None
self.ui = None
self._setup_ui()
@property
def presenter(self) -> 'PeaksViewerCollectionPresenter':
return self._presenter
def subscribe(self, presenter: 'PeaksViewerCollectionPresenter') -> None:
r"""
@brief Subscribe a presenter to the viever
@details The presenter must have method 'response_function' able to handle the event
"""
self._presenter = presenter
self._route_signals_to_presenter()
@property
def erasing_mode_on(self):
r"""Find if the button to remove peaks is checked"""
return self.ui.remove_peaks_button.isChecked()
@property
def adding_mode_on(self):
r"""Find if the button to add peaks is checked"""
return self.ui.add_peaks_button.isChecked()
@property
def active_peaksworkspace(self):
r"""Return the currently selected PeaksWorkspace."""
return self.ui.active_peaks_combobox.currentText()
def deactivate_peak_adding(self):
self.ui.add_peaks_button.setChecked(False)
self.ui.remove_peaks_button.setChecked(False)
def set_peaksworkspace(self, names):
"""Set the items in the combobox.
The names are sorted to prevent reordering when the workspace
is replaced in the ADS after adding or removing a peak.
The current name set back after we replace all the items.
"""
current_name = self.ui.active_peaks_combobox.currentText()
self.ui.active_peaks_combobox.clear()
self.ui.active_peaks_combobox.addItems(sorted(names))
self.ui.active_peaks_combobox.setCurrentText(current_name)
def _setup_ui(self):
self.ui = load_ui(__file__, 'actions.ui', self)
# Styling
self.ui.add_peaks_button.setStyleSheet("background-color:lightgrey")
self.ui.remove_peaks_button.setStyleSheet("background-color:lightgrey")
self.ui.add_peaks_button.clicked.connect(self._add_button_clicked)
self.ui.remove_peaks_button.clicked.connect(self._delete_button_clicked)
def _route_signals_to_presenter(self):
r"""Link viewer particular viewer signals to particular methods of the presenter"""
self.ui.add_peaks_button.clicked.connect(self.presenter.deactivate_zoom_pan)
self.ui.remove_peaks_button.clicked.connect(self.presenter.deactivate_zoom_pan)
def _add_button_clicked(self, state):
if state:
self.ui.remove_peaks_button.setChecked(False)
def _delete_button_clicked(self, state):
if state:
self.ui.add_peaks_button.setChecked(False)
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>peakActions</class>
<widget class="QWidget" name="peakActions">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>398</width>
<height>126</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>398</width>
<height>126</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>371</width>
<height>101</height>
</rect>
</property>
<property name="title">
<string>Peak Actions</string>
</property>
<widget class="QComboBox" name="active_peaks_combobox">
<property name="geometry">
<rect>
<x>10</x>
<y>30</y>
<width>221</width>
<height>31</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="add_peaks_button">
<property name="geometry">
<rect>
<x>250</x>
<y>30</y>
<width>111</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>Add Peaks</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton" name="remove_peaks_button">
<property name="geometry">
<rect>
<x>250</x>
<y>60</y>
<width>111</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>Remove Peaks</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
<widget class="Line" name="line">
<property name="geometry">
<rect>
<x>240</x>
<y>30</y>
<width>3</width>
<height>61</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>
......@@ -6,14 +6,18 @@
# SPDX - License - Identifier: GPL - 3.0 +
# This file is part of the mantid workbench.
# local imports
from mantidqt.widgets.workspacedisplay.table.model import TableWorkspaceDisplayModel
from .representation.draw import draw_peak_representation
from .representation.painter import Painted
# 3rd party imports
from mantid.api import AnalysisDataService
from mantid.api import AnalysisDataService, IPeaksWorkspace
from mantid.kernel import logger, SpecialCoordinateSystem
# local imports
from mantidqt.widgets.workspacedisplay.table.model \
import TableWorkspaceDisplayModel
from .representation.draw import draw_peak_representation
# standard library
import numpy as np
from typing import List
# map coordinate system to correct Peak getter
FRAME_TO_PEAK_CENTER_ATTR = {
......@@ -28,7 +32,10 @@ class PeaksViewerModel(TableWorkspaceDisplayModel):
Extends PeaksWorkspace functionality to include color selection
"""
def __init__(self, peaks_ws, fg_color, bg_color):
def __init__(self,
peaks_ws: IPeaksWorkspace,
fg_color: str,
bg_color: str):
"""
:param peaks_ws: A pointer to the PeaksWorkspace
:param fg_color: Color of the glyphs marking the signal region
......@@ -40,7 +47,7 @@ class PeaksViewerModel(TableWorkspaceDisplayModel):
super().__init__(peaks_ws)
self._fg_color = fg_color
self._bg_color = bg_color
self._representations = []
self._representations: List[Painted] = []
@property
def bg_color(self):
......@@ -80,6 +87,28 @@ class PeaksViewerModel(TableWorkspaceDisplayModel):
self._representations = representations
def add_peak(self, pos, frame):
"""Add a peak to the workspace using the given position and frame"""
self.peaks_workspace.addPeak(pos, frame)
def delete_peak(self, pos, frame):
r"""Delete the peak closest to the input position"""
if self.peaks_workspace.getNumberPeaks() == 0:
return
frame_to_slice_fn = self._frame_to_slice_fn(frame)
def unpack_pos(peak):
v3d_vector = getattr(peak, frame_to_slice_fn)()
return [v3d_vector.X(), v3d_vector.Y(), v3d_vector.Z()]
positions = np.array([unpack_pos(peak) for peak in self.peaks_workspace])
positions -= pos # peak positions relative to the input position
distances_squared = np.sum(positions * positions, axis=1)
closest_peak_index = np.argmin(distances_squared)
return self.peaks_workspace.removePeak(int(closest_peak_index)) # required cast from numpy.int64 to int
def slicepoint(self, selected_index, slice_info):
"""
Return the value of the center in the slice dimension for the peak at the given index
......@@ -122,7 +151,8 @@ class PeaksViewerModel(TableWorkspaceDisplayModel):
def create_peaksviewermodel(peaks_ws_name: str, fg_color: str, bg_color: str):
"""
A factory function to create a PeaksViewerModel from the given workspace name
A factory function to create a PeaksViewerModel from the given workspace name. Used by
the PeaksViewerColletionPresenter when appending a new PeaksWorkspace.
:param peaks_ws_name: A str giving a workspace name that is expected to be a PeaksWorkspace
:param fg_color: Color of the glyphs marking the signal region
:param bg_color: Color of the glyphs marking the background region
......
......@@ -6,14 +6,19 @@
# SPDX - License - Identifier: GPL - 3.0 +
# This file is part of the mantid workbench.
# std imports
from enum import Enum
# local imports
from .model import create_peaksviewermodel, PeaksViewerModel
from .view import PeaksViewerView, PeaksViewerCollectionView
from ..adsobsever import SliceViewerADSObserver
# 3rd party
from mantid.kernel import logger
from mantidqt.widgets.workspacedisplay.table.presenter_standard \
import TableWorkspaceDataPresenterStandard, create_table_item
from .model import create_peaksviewermodel
from ..adsobsever import SliceViewerADSObserver
# standard
from enum import Enum
from typing import List, Union
class PeaksWorkspaceDataPresenter(TableWorkspaceDataPresenterStandard):
......@@ -51,7 +56,9 @@ class PeaksViewerPresenter:
ClearPeaks = 4
PeakSelected = 5
def __init__(self, model, view):
def __init__(self,
model: PeaksViewerModel,
view: PeaksViewerView):
"""
Constructs the view for the given PeaksWorkspace
:param model: A handle to the view-model wrapper for PeaksWorkspace to be displayed
......@@ -61,9 +68,7 @@ class PeaksViewerPresenter:
super().__init__()
self._model = model
self._raise_error_if_workspace_incompatible(model.peaks_workspace)
self._peaks_table_presenter = \
PeaksWorkspaceDataPresenter(model, view.table_view)
self._peaks_table_presenter = PeaksWorkspaceDataPresenter(model, view.table_view)
self._view = view
view.subscribe(self)
view.set_title(model.peaks_workspace.name())
......@@ -78,7 +83,7 @@ class PeaksViewerPresenter:
def view(self):
return self._view
def notify(self, event):
def notify(self, event: Event):
"""
Notification of an event that the presenter should react to
:param event:
......@@ -96,6 +101,12 @@ class PeaksViewerPresenter:
from mantid.kernel import logger
logger.warning("PeaksViewer: Unknown event detected: {}".format(event))
def add_peak(self, pos):
self.model.add_peak(pos, self._view.sliceinfo.frame)
def delete_peak(self, pos):
self.model.delete_peak(pos, self._view.sliceinfo.frame)
def _clear_peaks(self):
"""Clear all peaks from this view"""
self.view.clear_table_selection()
......@@ -157,12 +168,14 @@ class PeaksViewerCollectionPresenter:
]
DEFAULT_BG_COLOR = '0.75'
def __init__(self, view):
def __init__(self, view: PeaksViewerCollectionView):
"""
:param view: View displaying the model information
"""
self._view = view
self._child_presenters = []
self._actions_view = view.peak_actions_view
self._actions_view.subscribe(self)
self._child_presenters: List[PeaksViewerPresenter] = []
self._ads_observer = None
self.setup_ads_observer()