Skip to content

Commit

Permalink
Implement IdentityAssigner for one FID object
Browse files Browse the repository at this point in the history
  • Loading branch information
torogi94 committed Sep 5, 2023
1 parent a6884d1 commit e05295d
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 3 deletions.
36 changes: 36 additions & 0 deletions nmrpy/data_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ def __init__(self, *args, **kwargs):
self.data = kwargs.get("data", [])
self.peaks = None
self.ranges = None
self.identities = None
self._deconvoluted_peaks = None
self._flags = {
"ft": False,
Expand Down Expand Up @@ -350,6 +351,24 @@ def ranges(self, ranges):
raise AttributeError("ranges must be numbers")
self._ranges = ranges

@property
def identities(self):
"""
Assigned identities corresponding to the various ranges in :attr:`~nmrpy.data_objects.Fid.ranges`.
"""
return self._identitites

@identities.setter
def identities(self, identities):
if identities is not None:
if not Fid._is_flat_iter(identities):
raise AttributeError("identitites must be a flat iterable")
if not all(isinstance(i, str) for i in identities):
raise AttributeError("identities must be strings")
self._identitites = numpy.array(identities)
else:
self._identities = identities

@property
def _bl_ppm(self):
return self.__bl_ppm
Expand Down Expand Up @@ -1382,6 +1401,23 @@ def plot_deconv(self, **kwargs):
setattr(self, plt.id, plt)
pyplot.show()

def assign_identities(self):
"""
Instantiate a identity-assignment GUI widget. Select a range from dropdown menu containing
:attr:`~nmrpy.data_objects.Fid.ranges`. Select a species from second dropdown menu
containing species defined in EnzymeML. When satisfied with assignment, press Assign button
to apply.
"""

widget_title = "Assign identitiy for {}".format(self.id)
self._assigner_widget = IdentityAssigner(fid=self, title=widget_title)

def clear_identities(self):
"""
Clear assigned identities stored in :attr:`~nmrpy.data_objects.Fid.identities`.
"""
self.identities = None


class FidArray(Base):
"""
Expand Down
105 changes: 102 additions & 3 deletions nmrpy/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from matplotlib.widgets import Cursor
from matplotlib.backend_bases import NavigationToolbar2, Event

from ipywidgets import FloatText, Output, VBox
from ipywidgets import FloatText, Output, VBox, Dropdown, Label, Button
from IPython.display import display
import asyncio

Expand Down Expand Up @@ -942,7 +942,7 @@ class Ssm:
transform=trans,
visible=False,
animated=True,
**self.ssm.rectprops
**self.ssm.rectprops,
)
self.ax.add_patch(self.ssm.rect)

Expand All @@ -957,7 +957,7 @@ def makespan(self, left, width):
transform=trans,
visible=True,
# animated=True,
**self.ssm.rectprops
**self.ssm.rectprops,
)
self.ax.add_patch(rect)
return rect
Expand Down Expand Up @@ -1376,6 +1376,105 @@ class SpanDataSelector(DataSelector, SpanSelectorMixin, AssignMixin):
pass


class IdentityAssigner:
def __init__(self, fid, title):
self.fid = fid
self.title = title
self.selected_values = {}
if fid.data is [] or fid.data is None:
raise ValueError("data must exist.")
if fid.peaks is [] or fid.peaks is None:
raise RuntimeError(
f"`fid.peaks` are required but still empty. Please either assign them manually or using the `peakpicker` method."
)

# Create the label widget for the title
title_label = Label(value=title)

# Create the dropdown widget for the peaks
peak_dropdown = Dropdown(
options=[str(peak) for peak in fid.peaks],
description="Select a peak:",
layout={"width": "max-content"},
style={"description_width": "initial"},
)

# Create the dropdown widget for the species
species_dropdown = Dropdown(
options=[],
description="Select a species:",
layout={"width": "max-content"},
style={"description_width": "initial"},
disabled=True,
)

# Create the button to save selection to dict
save_button = Button(
description="Save selection", icon="file-arrow-down", disabled=True
)

# Create an output widget to display the selection
selection_output = Output()

# Define a method to handle the peak dropdown's change event
def on_peak_dropdown_change(event):
if event["type"] == "change" and event["name"] == "value":
selected_option = event["new"]
if selected_option != "":
species_dropdown.options = [
"3PG",
"2PG",
"Phosphate",
"TEP",
"PEP",
]
species_dropdown.disabled = False
save_button.disabled = False

# Attach the function to the dropdown's change event
peak_dropdown.observe(on_peak_dropdown_change)

# Define a method to handle the species dropdown's change event
def on_species_dropdown_change(event):
if event["type"] == "change" and event["name"] == "value":
selected_option = event["new"]
if selected_option != "":
new_key = peak_dropdown.value
self.selected_values[new_key] = selected_option

# Attach the function to the second dropdown's change event
species_dropdown.observe(on_species_dropdown_change)

# Define a function to handle the save button click event
def on_save_button_click(b):
with selection_output:
selection_output.clear_output(wait=True)
print("\nSaved selections:")
for key, value in self.selected_values.items():
print(f"{key}: {value}")

# Attach the function to the save button's click event
save_button.on_click(on_save_button_click)

# Create a container for both the title and the dropdown
container = VBox(
[
title_label,
peak_dropdown,
species_dropdown,
save_button,
selection_output,
]
)

# Display the container
display(container)


class IdentityRangeAssigner:
...


class DataTraceSelector:
"""
Interactive data-selection widget with traces and ranges. Traces are saved
Expand Down

0 comments on commit e05295d

Please sign in to comment.