Skip to content

Commit

Permalink
Implement IdentityAssigner for entire FIDArray
Browse files Browse the repository at this point in the history
  • Loading branch information
torogi94 committed Sep 6, 2023
1 parent 95bbc7f commit 7cd28da
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 13 deletions.
44 changes: 36 additions & 8 deletions nmrpy/data_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,8 @@ def identities(self):
@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 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)
Expand Down Expand Up @@ -931,6 +931,12 @@ def clear_ranges(self):
"""
self.ranges = None

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

def baseliner(self):
"""
Instantiate a baseline-correction GUI widget. Right-click-dragging
Expand Down Expand Up @@ -1403,18 +1409,20 @@ def plot_deconv(self, **kwargs):

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.
Instantiate a identity-assignment GUI widget. Select peaks from
dropdown menu containing :attr:`~nmrpy.data_objects.Fid.peaks`.
Attach a species to the selected peak 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)
widget_title = "Assign identities 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`.
Clear assigned identities stored in
:attr:`~nmrpy.data_objects.Fid.identities`.
"""
self.identities = None

Expand Down Expand Up @@ -2342,6 +2350,26 @@ def save_data(self, file_format: str, filename=None, overwrite=False):
with open(filename, "w") as f:
f.write(model)

def assign_identities(self):
"""
Instantiate a identity-assignment GUI widget. Select a FID by
its ID from the combobox. Select peaks from dropdown menu
containing :attr:`~nmrpy.data_objects.Fid.peaks`. Attach a
species to the selected peak from second dropdown menu
containing species defined in EnzymeML. When satisfied with
assignment, press Assign button to apply.
"""

self._assigner_widget = IdentityRangeAssigner(fid_array=self)

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


class Importer(Base):
def __init__(self, *args, **kwargs):
Expand Down
142 changes: 137 additions & 5 deletions nmrpy/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,15 @@
from matplotlib.widgets import Cursor
from matplotlib.backend_bases import NavigationToolbar2, Event

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

Expand Down Expand Up @@ -1381,11 +1389,9 @@ 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."
f"`fid.peaks` is required but still empty. Please either assign them manually or using the `peakpicker` method."
)

# Create the label widget for the title
Expand Down Expand Up @@ -1452,6 +1458,9 @@ def on_save_button_click(b):
print("\nSaved selections:")
for key, value in self.selected_values.items():
print(f"{key}: {value}")
self.fid.identities = [
value for value in self.selected_values.values()
]

# Attach the function to the save button's click event
save_button.on_click(on_save_button_click)
Expand All @@ -1472,7 +1481,130 @@ def on_save_button_click(b):


class IdentityRangeAssigner:
...
"""Wow, such documentation.
for fid in [self.fids[i] for i in self.fid_number]:
"""

def __init__(self, fid_array):
self.fid_array = fid_array
self.fids = fid_array.get_fids()
self.selected_fid = None
self.selected_values = {}
for fid in self.fids:
if fid.peaks is [] or fid.peaks is None:
raise RuntimeError(
f"`fid.peaks` is 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="Assign identities for all FIDs")

# Create the combobox for the selection of the FID ID
combobox = Combobox(
options=[fid.id for fid in self.fids],
description="Select FID to base entire array on:",
layout={"width": "max-content"},
style={"description_width": "initial"},
)

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

# 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 selection in combobox
def on_combobox_change(event):
if event["type"] == "change" and event["name"] == "value":
selected_option = event["new"]
if selected_option in combobox.options:
peak_dropdown.disabled = False
self.selected_fid = self.fid_array.get_fid(selected_option)
peak_dropdown.options = [
str(peak) for peak in self.selected_fid.peaks
]

# Attach the method to the combobox's change event:
combobox.observe(on_combobox_change)

# 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 method 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}")
for fid in self.fids:
fid.identities = [
value for value in self.selected_values.values()
]

# 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,
combobox,
peak_dropdown,
species_dropdown,
save_button,
selection_output,
]
)

# Display the container
display(container)


class DataTraceSelector:
Expand Down

0 comments on commit 7cd28da

Please sign in to comment.