Skip to content

Commit 9c4fab2

Browse files
committed
first iteration
1 parent 3845cdc commit 9c4fab2

File tree

1 file changed

+163
-0
lines changed

1 file changed

+163
-0
lines changed

neo/rawio/baserawio.py

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,169 @@ def _repr_annotations(self):
406406
def print_annotations(self):
407407
"""Print formatted raw_annotations"""
408408
print(self._repr_annotations())
409+
410+
def _repr_html_(self):
411+
"""
412+
HTML representation for the raw recording base.
413+
414+
Returns
415+
-------
416+
html : str
417+
The HTML representation as a string.
418+
"""
419+
html = []
420+
html.append('<div style="font-family: Arial, sans-serif; max-width: 1000px; margin: 0 auto;">')
421+
422+
# Header
423+
html.append(f'<h3 style="color: #2c3e50;">{self.__class__.__name__}: {self.source_name()}</h3>')
424+
425+
if self.header is not None:
426+
# Basic info
427+
nb_block = self.block_count()
428+
html.append(f'<p><strong>nb_block:</strong> {nb_block}</p>')
429+
nb_seg = [self.segment_count(i) for i in range(nb_block)]
430+
html.append(f'<p><strong>nb_segment:</strong> {nb_seg}</p>')
431+
432+
# CSS for tables
433+
html.append('''
434+
<style>
435+
table.neo-table {
436+
border-collapse: collapse;
437+
width: 100%;
438+
margin-bottom: 20px;
439+
font-size: 14px;
440+
}
441+
table.neo-table th, table.neo-table td {
442+
border: 1px solid #ddd;
443+
padding: 8px;
444+
text-align: left;
445+
}
446+
table.neo-table th {
447+
background-color: #f2f2f2;
448+
color: #333;
449+
}
450+
table.neo-table tr:nth-child(even) {
451+
background-color: #f9f9f9;
452+
}
453+
details {
454+
margin-bottom: 15px;
455+
border: 1px solid #ddd;
456+
border-radius: 4px;
457+
overflow: hidden;
458+
}
459+
summary {
460+
padding: 10px;
461+
background-color: #f2f2f2;
462+
cursor: pointer;
463+
font-weight: bold;
464+
}
465+
details[open] summary {
466+
border-bottom: 1px solid #ddd;
467+
}
468+
.table-container {
469+
padding: 10px;
470+
overflow-x: auto;
471+
}
472+
</style>
473+
''')
474+
475+
# Signal Streams
476+
signal_streams = self.header["signal_streams"]
477+
if signal_streams.size > 0:
478+
html.append('<details>')
479+
html.append('<summary>Signal Streams</summary>')
480+
html.append('<div class="table-container">')
481+
html.append('<table class="neo-table">')
482+
html.append('<thead><tr><th>Name</th><th>ID</th><th>Buffer ID</th><th>Channel Count</th></tr></thead>')
483+
html.append('<tbody>')
484+
485+
for i, stream in enumerate(signal_streams):
486+
html.append('<tr>')
487+
html.append(f'<td>{stream["name"]}</td>')
488+
html.append(f'<td>{stream["id"]}</td>')
489+
html.append(f'<td>{stream["buffer_id"]}</td>')
490+
html.append(f'<td>{self.signal_channels_count(i)}</td>')
491+
html.append('</tr>')
492+
493+
html.append('</tbody></table>')
494+
html.append('</div>')
495+
html.append('</details>')
496+
497+
# Signal Channels
498+
signal_channels = self.header["signal_channels"]
499+
if signal_channels.size > 0:
500+
html.append('<details>')
501+
html.append('<summary>Signal Channels</summary>')
502+
html.append('<div class="table-container">')
503+
html.append('<table class="neo-table">')
504+
html.append('<thead><tr><th>Name</th><th>ID</th><th>Sampling Rate</th><th>Data Type</th><th>Units</th><th>Gain</th><th>Offset</th><th>Stream ID</th><th>Buffer ID</th></tr></thead>')
505+
html.append('<tbody>')
506+
507+
for channel in signal_channels:
508+
html.append('<tr>')
509+
html.append(f'<td>{channel["name"]}</td>')
510+
html.append(f'<td>{channel["id"]}</td>')
511+
html.append(f'<td>{channel["sampling_rate"]}</td>')
512+
html.append(f'<td>{channel["dtype"]}</td>')
513+
html.append(f'<td>{channel["units"]}</td>')
514+
html.append(f'<td>{channel["gain"]}</td>')
515+
html.append(f'<td>{channel["offset"]}</td>')
516+
html.append(f'<td>{channel["stream_id"]}</td>')
517+
html.append(f'<td>{channel["buffer_id"]}</td>')
518+
html.append('</tr>')
519+
520+
html.append('</tbody></table>')
521+
html.append('</div>')
522+
html.append('</details>')
523+
524+
# Spike Channels
525+
spike_channels = self.header["spike_channels"]
526+
if spike_channels.size > 0:
527+
html.append('<details>')
528+
html.append('<summary>Spike Channels</summary>')
529+
html.append('<div class="table-container">')
530+
html.append('<table class="neo-table">')
531+
html.append('<thead><tr><th>Name</th><th>ID</th><th>WF Units</th><th>WF Gain</th><th>WF Offset</th><th>WF Left Sweep</th><th>WF Sampling Rate</th></tr></thead>')
532+
html.append('<tbody>')
533+
534+
for channel in spike_channels:
535+
html.append('<tr>')
536+
html.append(f'<td>{channel["name"]}</td>')
537+
html.append(f'<td>{channel["id"]}</td>')
538+
html.append(f'<td>{channel["wf_units"]}</td>')
539+
html.append(f'<td>{channel["wf_gain"]}</td>')
540+
html.append(f'<td>{channel["wf_offset"]}</td>')
541+
html.append(f'<td>{channel["wf_left_sweep"]}</td>')
542+
html.append(f'<td>{channel["wf_sampling_rate"]}</td>')
543+
html.append('</tr>')
544+
545+
html.append('</tbody></table>')
546+
html.append('</div>')
547+
html.append('</details>')
548+
549+
# Event Channels
550+
event_channels = self.header["event_channels"]
551+
if event_channels.size > 0:
552+
html.append('<details>')
553+
html.append('<summary>Event Channels</summary>')
554+
html.append('<div class="table-container">')
555+
html.append('<table class="neo-table">')
556+
html.append('<thead><tr><th>Name</th><th>ID</th><th>Type</th></tr></thead>')
557+
html.append('<tbody>')
558+
559+
for channel in event_channels:
560+
html.append('<tr>')
561+
html.append(f'<td>{channel["name"]}</td>')
562+
html.append(f'<td>{channel["id"]}</td>')
563+
html.append(f'<td>{channel["type"].decode("utf-8") if isinstance(channel["type"], bytes) else channel["type"]}</td>')
564+
html.append('</tr>')
565+
566+
html.append('</tbody></table>')
567+
html.append('</div>')
568+
html.append('</details>')
569+
570+
html.append('</div>')
571+
return '\n'.join(html)
409572

410573
def block_count(self):
411574
"""Returns the number of blocks"""

0 commit comments

Comments
 (0)