Skip to content

Commit 2d0ad78

Browse files
committed
enh: report graphs in matplotlib
1 parent 86ed2c1 commit 2d0ad78

7 files changed

Lines changed: 231 additions & 223 deletions

File tree

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ dependencies = [
2525
"python-docx>=1.1",
2626
"docx2pdf>=0.1.8",
2727
"pydantic>=2.0",
28-
"pyqtgraph>=0.14.0",
2928
"pyside6>=6.11.0",
3029
"matplotlib>=3.5",
3130
]

src/clinical_dbs_annotator/utils/longitudinal_exporter.py

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -244,51 +244,49 @@ def get_file_datetime(path):
244244

245245
doc.add_paragraph("")
246246

247-
# Determine which sections to include (default: sessions_overview + session_data)
247+
# Determine which sections to include (default: sessions_overview + session_data children)
248248
all_keys = [
249249
"sessions_overview",
250250
"session_data",
251-
"session_data_overview_graph",
252-
"session_data_complete_table",
251+
"session_data_graph",
252+
"session_data_table",
253253
"electrode_config",
254254
"programming_summary",
255255
]
256-
active = (
257-
set(sections)
258-
if sections is not None
259-
else {"sessions_overview", "session_data"}
260-
)
256+
if sections is not None:
257+
active = set(sections)
258+
else:
259+
# Default: sessions_overview + both session_data children
260+
active = {"sessions_overview", "session_data_graph"}
261261

262262
# Render in the defined order
263263
for key in all_keys:
264264
if key not in active:
265265
continue
266266
if key == "sessions_overview":
267+
doc.add_paragraph("")
267268
self._add_sessions_overview(doc, df_all, file_paths)
269+
if key == "session_data":
270+
# Treat parent as both children
268271
doc.add_paragraph("")
269-
elif key == "session_data":
270-
# For backward compatibility, treat parent as both children
271272
doc.add_heading("Session Data", level=1)
272273
self._add_scales_timeline_chart(doc, df_session, file_paths)
273-
doc.add_paragraph("")
274274
self._add_longitudinal_data_table(
275275
doc,
276276
df_session,
277277
file_paths,
278278
include_chart=False,
279279
include_heading=False,
280280
)
281-
doc.add_paragraph("")
282-
elif key == "session_data_overview_graph":
281+
elif key == "session_data_graph":
283282
# Handle graph separately - add heading first
284-
if "session_data_complete_table" not in active:
285-
doc.add_heading("Session Data", level=1)
286-
self._add_scales_timeline_chart(doc, df_session, file_paths)
287283
doc.add_paragraph("")
288-
elif key == "session_data_complete_table":
284+
doc.add_heading("Session Data", level=1)
285+
self._add_scales_timeline_chart(doc, df_session, file_paths)
286+
elif key == "session_data_table":
289287
# Handle table separately - add heading first if graph not selected
290-
if "session_data_overview_graph" not in active:
291-
doc.add_heading("Session Data", level=1)
288+
doc.add_paragraph("")
289+
doc.add_heading("Session Data", level=1)
292290
self._add_longitudinal_data_table(
293291
doc,
294292
df_session,
@@ -297,12 +295,12 @@ def get_file_datetime(path):
297295
include_heading=False,
298296
)
299297
doc.add_paragraph("")
300-
elif key == "electrode_config":
298+
if key == "electrode_config":
299+
doc.add_paragraph("")
301300
self._add_electrode_config_section(doc, df_all, file_paths)
301+
if key == "programming_summary":
302302
doc.add_paragraph("")
303-
elif key == "programming_summary":
304303
self._add_programming_summary(doc, df_all, file_paths)
305-
doc.add_paragraph("")
306304

307305
doc.save(out_path)
308306
return True
@@ -949,7 +947,7 @@ def _add_scales_timeline_chart(
949947
scale_data,
950948
self.scale_optimization_prefs,
951949
title="Session Scale Trends",
952-
x_label="Session",
950+
x_label="Session Block",
953951
y_label="Scale Value",
954952
x_ticks=x_ticks,
955953
rotate_x_ticks=True,
@@ -1074,7 +1072,7 @@ def _collect_session_scale_data(
10741072
) -> tuple[dict[str, dict[int, float]], list[tuple[int, str]]]:
10751073
"""Collect all session scale values across files, one point per block per file.
10761074
1077-
X-tick labels: ``{date}_{block_ID}_{run_ID}``
1075+
X-tick labels: ``{date}_{run_ID}``
10781076
10791077
Returns:
10801078
(scale_data, x_ticks)
@@ -1110,13 +1108,19 @@ def _collect_session_scale_data(
11101108
run_id = self._extract_run_from_filename(src)
11111109

11121110
blocks = sorted(df_src["block_id"].unique())
1113-
for bid in blocks:
1111+
for i, bid in enumerate(blocks):
11141112
point_keys.append((src, bid))
11151113
bid_str = str(int(bid)) if bid == int(bid) else str(bid)
1116-
parts = [date_str, bid_str]
1117-
if run_id:
1118-
parts.append(run_id)
1119-
tick_labels.append("_".join(parts))
1114+
if i == 0:
1115+
# First block: full label {date}_{run_id}_{block_id}
1116+
parts = [date_str]
1117+
if run_id:
1118+
parts.append(run_id)
1119+
parts.append(bid_str)
1120+
tick_labels.append("_".join(parts))
1121+
else:
1122+
# Subsequent blocks: only block_id
1123+
tick_labels.append(bid_str)
11201124

11211125
if not point_keys:
11221126
return {}, []
@@ -1177,6 +1181,12 @@ def _create_lateral_table(self, df: pd.DataFrame) -> pd.DataFrame:
11771181

11781182
df = self._normalize_block_id(df)
11791183

1184+
# Sort by source file (chronological order) and block_id (ascending)
1185+
if "_source_file" in df.columns:
1186+
df = df.sort_values(by=["_source_file", "block_id"], ascending=[True, True])
1187+
elif "block_id" in df.columns:
1188+
df = df.sort_values(by=["block_id"], ascending=True)
1189+
11801190
# Create a global entry id combining source file + block_id
11811191
if "_source_file" in df.columns and "block_id" in df.columns:
11821192
df["_global_entry_id"] = (

0 commit comments

Comments
 (0)