Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

037 implement eeli wbaccinelli #42

Merged
merged 31 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c0e0505
create analyze page
wbaccinelli Apr 15, 2024
a338691
refactored to use eit as continuous data
wbaccinelli Apr 16, 2024
cd0936f
create analyze page
wbaccinelli Apr 15, 2024
73a7df0
refactored to use eit as continuous data
wbaccinelli Apr 16, 2024
2869ac2
Merge branch '037_implement_eeli_wbaccinelli' of https://github.com/E…
wbaccinelli Apr 16, 2024
fd78ecc
small changes
wbaccinelli Apr 16, 2024
d53379f
summary cards
wbaccinelli Apr 17, 2024
b1f9ae1
adding graph container
wbaccinelli Apr 17, 2024
6d17aaf
create analyze page
wbaccinelli Apr 15, 2024
5380fc6
refactored to use eit as continuous data
wbaccinelli Apr 16, 2024
3f42db5
small changes
wbaccinelli Apr 16, 2024
3dd6494
summary cards
wbaccinelli Apr 17, 2024
67141d8
adding graph container
wbaccinelli Apr 17, 2024
6ff3456
Merge branch '037_implement_eeli_wbaccinelli' of https://github.com/E…
wbaccinelli Apr 17, 2024
1aa4bff
saving derived from and running eeli
wbaccinelli Apr 17, 2024
9369cc3
saving derived from and running eeli
wbaccinelli Apr 17, 2024
00cb323
plotting results
wbaccinelli Apr 17, 2024
43fbaf2
updating data loaded cards
wbaccinelli Apr 17, 2024
d051015
Merge branch 'main' into 037_implement_eeli_wbaccinelli
wbaccinelli Apr 17, 2024
4a5d9fe
linting
wbaccinelli Apr 18, 2024
98a0616
linting
wbaccinelli Apr 18, 2024
8dd20c6
pointing to the eeli branch
wbaccinelli Apr 18, 2024
9ee669d
formatting
wbaccinelli Apr 18, 2024
96eae5b
fixing filter
wbaccinelli Apr 18, 2024
8f8fe41
fixing filtered label
wbaccinelli Apr 18, 2024
242c242
updating the manual
wbaccinelli Apr 18, 2024
7cc0717
Update docs/user_manual.md
wbaccinelli Apr 18, 2024
84cf4fd
adding note to manual
wbaccinelli Apr 18, 2024
c28463e
Merge branch '037_implement_eeli_wbaccinelli' of https://github.com/E…
wbaccinelli Apr 18, 2024
3c0b3a7
using available data
wbaccinelli Apr 18, 2024
d758b17
linting
wbaccinelli Apr 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added docs/images/apply_eeli.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions docs/user_manual.md
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a note at the very top asking people to open issues if they encounter anything?

Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,12 @@ the preview will update. When you are happy with a particular setting/selection,
<kbd>
<img src=images/preprocessing_filter.png width="800px" style="border: 1px solid black">
</kbd>
wbaccinelli marked this conversation as resolved.
Show resolved Hide resolved

## ANALYZE page

Click `Apply EELI` to run EELI analysis. When the analysis is completed, it is possible to see
the results by selecting the period to visualize using the dropdown menu.

<kbd>
<img src=images/apply_eeli.png width="800px" style="border: 1px solid black">
</kbd>
164 changes: 164 additions & 0 deletions eit_dash/callbacks/analyze_callbacks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import plotly.graph_objects as go
from dash import Input, Output, State, callback, ctx
from eitprocessing.parameters.eeli import EELI

import eit_dash.definitions.element_ids as ids
import eit_dash.definitions.layout_styles as styles
from eit_dash.app import data_object
from eit_dash.definitions.constants import FILTERED_EIT_LABEL
from eit_dash.utils.common import (
create_filter_results_card,
create_info_card,
create_selected_period_card,
)

eeli = []


@callback(
Output(ids.SUMMARY_COLUMN_ANALYZE, "children", allow_duplicate=True),
Output(ids.ANALYZE_SELECT_PERIOD_VIEW, "options"),
[
Input(ids.ANALYZE_RESULTS_TITLE, "children"),
],
[
State(ids.SUMMARY_COLUMN_ANALYZE, "children"),
],
# this allows duplicate outputs with initial call
prevent_initial_call="initial_duplicate",
)
def page_setup(_, summary):
"""Setups the page elements when it starts up.

When the page is loaded, it populates the summary column
with the info about the loaded datasets and the preprocessing steps.
Populates the periods selections element with the loaded periods.
"""
trigger = ctx.triggered_id
options = []

if trigger is None:
for d in data_object.get_all_sequences():
card = create_info_card(d)
summary += [card]

filter_params = {}

for period in data_object.get_all_stable_periods():
if not filter_params:
filter_params = (
period.get_data()
.continuous_data.data[FILTERED_EIT_LABEL]
.parameters
)

summary += [
create_selected_period_card(
period.get_data(),
period.get_dataset_index(),
period.get_period_index(),
False,
),
]

# populate period selection
options.append(
{
"label": f"Period {period.get_period_index()}",
"value": period.get_period_index(),
},
)

summary += [create_filter_results_card(filter_params)]

return summary, options


@callback(
Output(ids.EELI_RESULTS_GRAPH_DIV, "hidden"),
Input(ids.EELI_APPLY, "n_clicks"),
prevent_initial_call=True,
)
def apply_eeli(_):
"""Apply EELI and store results."""
global eeli # noqa: PLW0602

eeli.clear()

periods = data_object.get_all_stable_periods()

for period in periods:
sequence = period.get_data()
eeli_result_filtered = EELI().compute_parameter(sequence, FILTERED_EIT_LABEL)

# TODO: the results should be stored in the sequence object
eeli_result_filtered["index"] = period.get_period_index()

eeli.append(eeli_result_filtered)

return False


@callback(
[
Output(ids.EELI_RESULTS_GRAPH, "figure"),
Output(ids.EELI_RESULTS_GRAPH, "style"),
],
Input(ids.ANALYZE_SELECT_PERIOD_VIEW, "value"),
prevent_initial_call=True,
)
def show_eeli(selected):
"""Show the results of the EELI for the selected period."""
figure = go.Figure()

sequence = data_object.get_stable_period(int(selected)).get_data()
for e in eeli:
if e["index"] == int(selected):
result = e

figure.add_trace(
go.Scatter(
x=sequence.continuous_data[FILTERED_EIT_LABEL].time,
y=sequence.continuous_data[FILTERED_EIT_LABEL].values,
name=FILTERED_EIT_LABEL,
),
)

figure.add_hline(y=result["mean"], line_color="red", name="Mean")
figure.add_hline(y=result["median"], line_color="red", name="Median")

figure.add_scatter(
x=sequence.continuous_data[FILTERED_EIT_LABEL].time[result["indices"]],
y=result["values"],
line_color="black",
name="EELIs",
mode="markers",
)

sd_upper = result["mean"] + result["standard deviation"]
sd_lower = result["mean"] - result["standard deviation"]

figure.add_trace(
go.Scatter(
x=sequence.continuous_data[FILTERED_EIT_LABEL].time,
y=[sd_upper] * len(sequence.continuous_data[FILTERED_EIT_LABEL].time),
fill=None,
mode="lines",
line_color="rgba(0,0,255,0)", # Set to transparent blue
name="Standard deviation",
),
)

# Add the lower bound line
figure.add_trace(
go.Scatter(
x=sequence.continuous_data[FILTERED_EIT_LABEL].time,
y=[sd_lower] * len(sequence.continuous_data[FILTERED_EIT_LABEL].time),
fill="tonexty", # Fill area below this line
mode="lines",
line_color="rgba(0,0,255,0.3)", # Set to semi-transparent blue
name="Standard deviation",
),
)

return figure, styles.GRAPH
64 changes: 17 additions & 47 deletions eit_dash/callbacks/load_callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import os
from pathlib import Path

import dash_bootstrap_components as dbc
import plotly.graph_objects as go
from dash import ALL, Input, Output, State, callback, ctx, html
from dash.exceptions import PreventUpdate
Expand All @@ -15,9 +14,10 @@

import eit_dash.definitions.element_ids as ids
from eit_dash.app import data_object
from eit_dash.definitions import layout_styles as styles
from eit_dash.definitions.constants import RAW_EIT_LABEL
from eit_dash.definitions.option_lists import InputFiletypes
from eit_dash.utils.common import (
create_info_card,
create_slider_figure,
get_selections_slidebar,
get_signal_options,
Expand All @@ -26,35 +26,6 @@
file_data: Sequence | None = None


def create_info_card(dataset: Sequence, file_type: int) -> dbc.Card:
"""Create the card with the information on the loaded dataset to be displayed in the Results section.

Args:
dataset: Sequence object containing the selected dataset
file_type: Index of the selected type of selected
"""
info_data = {
"Name": dataset.eit_data["raw"].path.name,
"n_frames": dataset.eit_data["raw"].nframes,
"start_time": dataset.eit_data["raw"].time[0],
"end_time": dataset.eit_data["raw"].time[-1],
"vendor": dataset.eit_data["raw"].vendor,
"continuous signals": str(list(dataset.continuous_data)),
"path": str(dataset.eit_data["raw"].path),
}

card_list = [
html.H4(dataset.label, className="card-title"),
html.H6(InputFiletypes(file_type).name, className="card-subtitle"),
]
card_list += [
dbc.Row(f"{data}: {value}", style=styles.INFO_CARD)
for data, value in info_data.items()
]

return dbc.Card(dbc.CardBody(card_list), id="card-1")


# managing the file selection. Confirm button clicked
@callback(
Output(ids.CHOOSE_DATA_POPUP, "is_open"),
Expand Down Expand Up @@ -134,13 +105,13 @@ def open_data_selector(data, cancel_load, sig, file_type, fig):

trigger = ctx.triggered_id

# cancelled selection. Reset the data and turn of the data selector
# cancelled selection. Reset the data and turn off the data selector
if trigger == ids.LOAD_CANCEL_BUTTON:
data = None
file_data = None

if not data:
# this is needed, because a figure object must be returned for the graph, evn if empty
# this is needed, because a figure object must be returned for the graph, even if empty
figure = go.Figure()
return True, [], figure

Expand All @@ -160,12 +131,11 @@ def open_data_selector(data, cancel_load, sig, file_type, fig):

figure = create_slider_figure(
file_data,
["raw"],
list(file_data.continuous_data),
True,
continuous_data=list(file_data.continuous_data),
clickable_legend=True,
)

ok = ["raw"]
ok = [RAW_EIT_LABEL]
if sig:
ok += [options[s]["label"] for s in sig]

Expand Down Expand Up @@ -205,12 +175,12 @@ def show_info(
start_sample, stop_sample = get_selections_slidebar(slidebar_stat)

if not start_sample:
start_sample = file_data.eit_data["raw"].time[0]
start_sample = file_data.continuous_data[RAW_EIT_LABEL].time[0]
if not stop_sample:
stop_sample = file_data.eit_data["raw"].time[-1]
stop_sample = file_data.continuous_data[RAW_EIT_LABEL].time[-1]
else:
start_sample = file_data.eit_data["raw"].time[0]
stop_sample = file_data.eit_data["raw"].time[-1]
start_sample = file_data.continuous_data[RAW_EIT_LABEL].time[0]
stop_sample = file_data.continuous_data[RAW_EIT_LABEL].time[-1]

dataset_name = f"Dataset {data_object.get_sequence_list_length()}"

Expand All @@ -227,8 +197,8 @@ def show_info(
eit_data_cut.add(data[data_type].select_by_time(start_sample, stop_sample))

for data_type in (data := file_data.continuous_data):
# add just the selected signals
if data_type in selected:
# add just the selected signals and the raw EIT
if data_type in selected or data_type == RAW_EIT_LABEL:
continuous_data_cut.add(
data[data_type].select_by_time(start_sample, stop_sample),
)
Expand All @@ -244,7 +214,7 @@ def show_info(
data_object.add_sequence(cut_data)

# create the info summary card
card = create_info_card(cut_data, int(filetype))
card = create_info_card(cut_data)

# add the card to the current results
if container_state:
Expand Down Expand Up @@ -284,9 +254,7 @@ def list_cwd_files(cwd):
full_path = Path(cwd) / filepath

is_dir = Path(full_path).is_dir()
extension = (
filepath.suffix if not filepath.name.startswith(".") else filepath.name
)
extension = filepath.suffix if not filepath.name.startswith(".") else filepath.name

if is_dir or extension in [".bin", ".txt", ".zri"]:
link = html.A(
Expand Down Expand Up @@ -320,3 +288,5 @@ def store_clicked_file(n_clicks, title):
for state in ctx.states_list[0]:
if state["id"]["index"] == index:
return state["value"]

return None
Loading
Loading