Skip to content

Commit ef0e844

Browse files
drammocksnwnde
authored andcommitted
Collapsible html repr for raw/info (mne-tools#12064)
Co-buthored-by: Valerii Chirkov <vagechirkov@gmail.com>
1 parent ad005d7 commit ef0e844

File tree

9 files changed

+98
-31
lines changed

9 files changed

+98
-31
lines changed

mne/_fiff/meas_info.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import operator
1515
from textwrap import shorten
1616
import string
17+
import uuid
1718

1819
import numpy as np
1920

@@ -1884,7 +1885,7 @@ def _get_chs_for_repr(self):
18841885
return good_channels, bad_channels, ecg, eog
18851886

18861887
@repr_html
1887-
def _repr_html_(self, caption=None):
1888+
def _repr_html_(self, caption=None, duration=None, filenames=None):
18881889
"""Summarize info for HTML representation."""
18891890
if isinstance(caption, str):
18901891
html = f"<h4>{caption}</h4>"
@@ -1916,7 +1917,11 @@ def _repr_html_(self, caption=None):
19161917
projs = None
19171918

19181919
info_template = _get_html_template("repr", "info.html.jinja")
1920+
sections = ("General", "Channels", "Data")
1921+
section_ids = [f"section_{str(uuid.uuid4())}" for _ in sections]
19191922
return html + info_template.render(
1923+
sections=sections,
1924+
section_ids=section_ids,
19201925
caption=caption,
19211926
meas_date=meas_date,
19221927
projs=projs,
@@ -1930,6 +1935,8 @@ def _repr_html_(self, caption=None):
19301935
highpass=self.get("highpass"),
19311936
sfreq=self.get("sfreq"),
19321937
experimenter=self.get("experimenter"),
1938+
duration=duration,
1939+
filenames=filenames,
19331940
)
19341941

19351942
def save(self, fname):

mne/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ def pytest_configure(config):
158158
# h5py
159159
ignore:`product` is deprecated as of NumPy.*:DeprecationWarning
160160
# pandas
161-
ignore:.*np\.find_common_type is deprecated.*:DeprecationWarning
161+
ignore:In the future `np.long`.*:FutureWarning
162162
# https://github.com/joblib/joblib/issues/1454
163163
ignore:.*`byte_bounds` is dep.*:DeprecationWarning
164164
# numpy distutils used by SciPy
Lines changed: 80 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,65 @@
1+
<style>
2+
label { cursor: pointer; }
3+
#{{ section_ids[0] }} ~ table [for="{{ section_ids[0] }}"]::before,
4+
#{{ section_ids[1] }} ~ table [for="{{ section_ids[1] }}"]::before,
5+
#{{ section_ids[2] }} ~ table [for="{{ section_ids[2] }}"]::before {
6+
display: inline-block;
7+
content: "";
8+
font-size: 11px;
9+
width: 15px;
10+
text-align: left;
11+
}
12+
13+
#{{ section_ids[0] }}:checked ~ table [for="{{ section_ids[0] }}"]::before,
14+
#{{ section_ids[1] }}:checked ~ table [for="{{ section_ids[1] }}"]::before,
15+
#{{ section_ids[2] }}:checked ~ table [for="{{ section_ids[2] }}"]::before {
16+
content: "";
17+
}
18+
19+
#{{ section_ids[0] }} ~ table tr.{{ section_ids[0] }},
20+
#{{ section_ids[1] }} ~ table tr.{{ section_ids[1] }},
21+
#{{ section_ids[2] }} ~ table tr.{{ section_ids[2] }} {
22+
visibility: collapse;
23+
}
24+
25+
#{{ section_ids[0] }}:checked ~ table tr.{{ section_ids[0] }},
26+
#{{ section_ids[1] }}:checked ~ table tr.{{ section_ids[1] }},
27+
#{{ section_ids[2] }}:checked ~ table tr.{{ section_ids[2] }} {
28+
visibility: visible;
29+
}
30+
</style>
31+
32+
<input type="checkbox" id="{{ section_ids[0] }}" hidden aria-hidden="true"/>
33+
<input type="checkbox" id="{{ section_ids[1] }}" hidden aria-hidden="true"/>
34+
<input type="checkbox" id="{{ section_ids[2] }}" hidden aria-hidden="true"/>
35+
136
<table class="table table-hover table-striped table-sm table-responsive small">
237
<tr>
38+
<th class="collapsible_header" colspan="2" style="font-weight: bold; text-align: left;">
39+
<label for={{ section_ids[0] }}>
40+
{{sections[0]}}
41+
</label>
42+
</th>
43+
</tr>
44+
<tr class="{{ section_ids[0] }}">
345
<th>Measurement date</th>
446
{% if meas_date is not none %}
547
<td>{{ meas_date }}</td>
648
{% else %}
749
<td>Unknown</td>
850
{% endif %}
951
</tr>
10-
<tr>
52+
<tr class="{{ section_ids[0] }}">
1153
<th>Experimenter</th>
1254
{% if experimenter is not none %}
1355
<td>{{ experimenter }}</td>
1456
{% else %}
1557
<td>Unknown</td>
1658
{% endif %}
1759
</tr>
60+
<tr class="{{ section_ids[0] }}">
1861
<th>Participant</th>
19-
{% if subject_info is not none %}
62+
{% if subject_info is defined and subject_info is not none %}
2063
{% if 'his_id' in subject_info.keys() %}
2164
<td>{{ subject_info['his_id'] }}</td>
2265
{% endif %}
@@ -25,50 +68,77 @@
2568
{% endif %}
2669
</tr>
2770
<tr>
71+
<th class="collapsible_header" colspan="2" style="font-weight: bold; text-align: left;">
72+
<label for={{ section_ids[1] }}>
73+
{{sections[1]}}
74+
</label>
75+
</th>
76+
</tr>
77+
<tr class="{{ section_ids[1] }}">
2878
<th>Digitized points</th>
2979
{% if dig is not none %}
3080
<td>{{ dig|length }} points</td>
3181
{% else %}
3282
<td>Not available</td>
3383
{% endif %}
3484
</tr>
35-
<tr>
85+
<tr class="{{ section_ids[1] }}">
3686
<th>Good channels</th>
3787
<td>{{ good_channels }}</td>
3888
</tr>
39-
<tr>
89+
<tr class="{{ section_ids[1] }}">
4090
<th>Bad channels</th>
4191
<td>{{ bad_channels }}</td>
4292
</tr>
43-
<tr>
93+
<tr class="{{ section_ids[1] }}">
4494
<th>EOG channels</th>
4595
<td>{{ eog }}</td>
4696
</tr>
47-
<tr>
97+
<tr class="{{ section_ids[1] }}">
4898
<th>ECG channels</th>
4999
<td>{{ ecg }}</td>
50-
{% if sfreq is not none %}
100+
</tr>
51101
<tr>
102+
<th class="collapsible_header" colspan="2" style="font-weight: bold; text-align: left;">
103+
<label for={{ section_ids[2] }}>
104+
{{sections[2]}}
105+
</label>
106+
</th>
107+
</tr>
108+
{% if sfreq is not none %}
109+
<tr class="{{ section_ids[2] }}">
52110
<th>Sampling frequency</th>
53111
<td>{{ '%0.2f'|format(sfreq) }} Hz</td>
54112
</tr>
55113
{% endif %}
56114
{% if highpass is not none %}
57-
<tr>
115+
<tr class="{{ section_ids[2] }}">
58116
<th>Highpass</th>
59117
<td>{{ '%0.2f'|format(highpass) }} Hz</td>
60118
</tr>
61119
{% endif %}
62120
{% if lowpass is not none %}
63-
<tr>
121+
<tr class="{{ section_ids[2] }}">
64122
<th>Lowpass</th>
65123
<td>{{ '%0.2f'|format(lowpass) }} Hz</td>
66124
</tr>
67125
{% endif %}
68126
{% if projs is not none %}
69-
<tr>
127+
<tr class="{{ section_ids[2] }}">
70128
<th>Projections</th>
71129
<td>{{ projs|join('<br/>') | safe }}</td>
72130
</tr>
73131
{% endif %}
132+
{% if filenames %}
133+
<tr class="{{section_ids[2]}}">
134+
<th>Filenames</th>
135+
<td>{{ filenames|join('<br>') }}</td>
136+
</tr>
137+
{% endif %}
138+
{% if duration %}
139+
<tr class="{{section_ids[2]}}">
140+
<th>Duration</th>
141+
<td>{{ duration }} (HH:MM:SS)</td>
142+
</tr>
143+
{% endif %}
74144
</table>
Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1 @@
1-
{{ info_repr[:-9] | safe }}
2-
{% if filenames %}
3-
<tr>
4-
<th>Filenames</th>
5-
<td>{{ filenames|join('<br>') }}</td>
6-
</tr>
7-
{% endif %}
8-
<tr>
9-
<th>Duration</th>
10-
<td>{{ duration }} (HH:MM:SS)</td>
11-
</tr>
12-
</table>
1+
{{ info_repr | safe }}

mne/io/base.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2069,9 +2069,11 @@ def _repr_html_(self, caption=None):
20692069
duration = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}"
20702070
raw_template = _get_html_template("repr", "raw.html.jinja")
20712071
return raw_template.render(
2072-
info_repr=self.info._repr_html_(caption=caption),
2073-
filenames=basenames,
2074-
duration=duration,
2072+
info_repr=self.info._repr_html_(
2073+
caption=caption,
2074+
filenames=basenames,
2075+
duration=duration,
2076+
)
20752077
)
20762078

20772079
def add_events(self, events, stim_channel=None, replace=False):

mne/utils/tests/test_misc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def test_html_repr():
2424
os.environ[key] = "True" # HTML repr on
2525
info = mne.create_info(10, 256)
2626
r = info._repr_html_()
27-
assert r.startswith("<table")
27+
assert r.startswith("<style")
2828
assert r.endswith("</table>")
2929
os.environ[key] = "False" # HTML repr off
3030
r = info._repr_html_()

tutorials/intro/30_info.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@
182182
print(mne.pick_info(info, eeg_indices)["nchan"])
183183

184184
# %%
185-
# We can also get a nice HTML representation in IPython like:
185+
# We can also get a nice HTML representation in IPython like this:
186186

187187
info
188188

tutorials/intro/70_report.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
HTML pages it generates are self-contained and do not require a running Python
1818
environment. However, it is less flexible as you can't change code and re-run
1919
something directly within the browser. This tutorial covers the basics of
20-
building a report. As usual, we'll start by importing the modules and data we
20+
building a report. As usual, we will start by importing the modules and data we
2121
need:
2222
"""
2323

tutorials/raw/10_raw_overview.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
"""
1818

1919
# %%
20-
2120
import os
2221
import numpy as np
2322
import matplotlib.pyplot as plt

0 commit comments

Comments
 (0)