figpack 0.1.2__py3-none-any.whl → 0.1.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of figpack might be problematic. Click here for more details.
- figpack/__init__.py +3 -1
- figpack/cli.py +312 -0
- figpack/figpack-gui-dist/assets/{index-BA_v5Jep.css → index-BDa2iJW9.css} +1 -1
- figpack/figpack-gui-dist/assets/index-Dw14QqeQ.js +846 -0
- figpack/figpack-gui-dist/index.html +2 -2
- figpack/spike_sorting/__init__.py +5 -0
- figpack/spike_sorting/views/AutocorrelogramItem.py +41 -0
- figpack/spike_sorting/views/Autocorrelograms.py +76 -0
- figpack/spike_sorting/views/CrossCorrelogramItem.py +45 -0
- figpack/spike_sorting/views/CrossCorrelograms.py +82 -0
- figpack/spike_sorting/views/UnitSimilarityScore.py +40 -0
- figpack/spike_sorting/views/UnitsTable.py +68 -0
- figpack/spike_sorting/views/UnitsTableColumn.py +40 -0
- figpack/spike_sorting/views/UnitsTableRow.py +36 -0
- figpack/spike_sorting/views/__init__.py +23 -0
- figpack/views/Image.py +82 -0
- figpack/views/Markdown.py +34 -0
- figpack/views/MatplotlibFigure.py +65 -0
- figpack/views/PlotlyFigure.py +58 -0
- figpack/views/__init__.py +4 -0
- {figpack-0.1.2.dist-info → figpack-0.1.4.dist-info}/METADATA +23 -1
- figpack-0.1.4.dist-info/RECORD +38 -0
- figpack-0.1.4.dist-info/entry_points.txt +2 -0
- figpack-0.1.4.dist-info/top_level.txt +1 -0
- figpack/figpack-gui-dist/assets/index-CMzZutX1.js +0 -78
- figpack-0.1.2.dist-info/RECORD +0 -23
- figpack-0.1.2.dist-info/top_level.txt +0 -2
- figpack-gui/node_modules/flatted/python/flatted.py +0 -149
- {figpack-0.1.2.dist-info → figpack-0.1.4.dist-info}/WHEEL +0 -0
- {figpack-0.1.2.dist-info → figpack-0.1.4.dist-info}/licenses/LICENSE +0 -0
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<link rel="icon" type="image/png" href="./assets/neurosift-logo-CLsuwLMO.png" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>figpack figure</title>
|
|
8
|
-
<script type="module" crossorigin src="./assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
8
|
+
<script type="module" crossorigin src="./assets/index-Dw14QqeQ.js"></script>
|
|
9
|
+
<link rel="stylesheet" crossorigin href="./assets/index-BDa2iJW9.css">
|
|
10
10
|
</head>
|
|
11
11
|
<body>
|
|
12
12
|
<div id="root"></div>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AutocorrelogramItem for spike sorting views
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Union
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AutocorrelogramItem:
|
|
10
|
+
"""
|
|
11
|
+
Represents a single autocorrelogram for a unit
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
*,
|
|
17
|
+
unit_id: Union[str, int],
|
|
18
|
+
bin_edges_sec: np.ndarray,
|
|
19
|
+
bin_counts: np.ndarray,
|
|
20
|
+
):
|
|
21
|
+
"""
|
|
22
|
+
Initialize an AutocorrelogramItem
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
unit_id: Identifier for the unit
|
|
26
|
+
bin_edges_sec: Array of bin edges in seconds
|
|
27
|
+
bin_counts: Array of bin counts
|
|
28
|
+
"""
|
|
29
|
+
self.unit_id = unit_id
|
|
30
|
+
self.bin_edges_sec = np.array(bin_edges_sec, dtype=np.float32)
|
|
31
|
+
self.bin_counts = np.array(bin_counts, dtype=np.int32)
|
|
32
|
+
|
|
33
|
+
def to_dict(self):
|
|
34
|
+
"""
|
|
35
|
+
Convert the autocorrelogram item to a dictionary representation
|
|
36
|
+
"""
|
|
37
|
+
return {
|
|
38
|
+
"unit_id": str(self.unit_id),
|
|
39
|
+
"bin_edges_sec": self.bin_edges_sec.tolist(),
|
|
40
|
+
"bin_counts": self.bin_counts.tolist(),
|
|
41
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Autocorrelograms view for figpack - displays multiple autocorrelograms
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import zarr
|
|
6
|
+
import numpy as np
|
|
7
|
+
from typing import List, Optional
|
|
8
|
+
from ...core.figpack_view import FigpackView
|
|
9
|
+
from .AutocorrelogramItem import AutocorrelogramItem
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Autocorrelograms(FigpackView):
|
|
13
|
+
"""
|
|
14
|
+
A view that displays multiple autocorrelograms for spike sorting analysis
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
*,
|
|
20
|
+
autocorrelograms: List[AutocorrelogramItem],
|
|
21
|
+
height: Optional[int] = 400,
|
|
22
|
+
):
|
|
23
|
+
"""
|
|
24
|
+
Initialize an Autocorrelograms view
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
autocorrelograms: List of AutocorrelogramItem objects
|
|
28
|
+
height: Height of the view in pixels
|
|
29
|
+
"""
|
|
30
|
+
self.autocorrelograms = autocorrelograms
|
|
31
|
+
self.height = height
|
|
32
|
+
|
|
33
|
+
def _write_to_zarr_group(self, group: zarr.Group) -> None:
|
|
34
|
+
"""
|
|
35
|
+
Write the Autocorrelograms data to a Zarr group
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
group: Zarr group to write data into
|
|
39
|
+
"""
|
|
40
|
+
# Set the view type
|
|
41
|
+
group.attrs["view_type"] = "Autocorrelograms"
|
|
42
|
+
|
|
43
|
+
# Set view properties
|
|
44
|
+
if self.height is not None:
|
|
45
|
+
group.attrs["height"] = self.height
|
|
46
|
+
|
|
47
|
+
# Store the number of autocorrelograms
|
|
48
|
+
group.attrs["num_autocorrelograms"] = len(self.autocorrelograms)
|
|
49
|
+
|
|
50
|
+
# Store metadata for each autocorrelogram
|
|
51
|
+
autocorrelogram_metadata = []
|
|
52
|
+
for i, autocorr in enumerate(self.autocorrelograms):
|
|
53
|
+
autocorr_name = f"autocorrelogram_{i}"
|
|
54
|
+
|
|
55
|
+
# Store metadata
|
|
56
|
+
metadata = {
|
|
57
|
+
"name": autocorr_name,
|
|
58
|
+
"unit_id": str(autocorr.unit_id),
|
|
59
|
+
"num_bins": len(autocorr.bin_counts),
|
|
60
|
+
}
|
|
61
|
+
autocorrelogram_metadata.append(metadata)
|
|
62
|
+
|
|
63
|
+
# Create arrays for this autocorrelogram
|
|
64
|
+
group.create_dataset(
|
|
65
|
+
f"{autocorr_name}/bin_edges_sec",
|
|
66
|
+
data=autocorr.bin_edges_sec,
|
|
67
|
+
dtype=np.float32,
|
|
68
|
+
)
|
|
69
|
+
group.create_dataset(
|
|
70
|
+
f"{autocorr_name}/bin_counts",
|
|
71
|
+
data=autocorr.bin_counts,
|
|
72
|
+
dtype=np.int32,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# Store the autocorrelogram metadata
|
|
76
|
+
group.attrs["autocorrelograms"] = autocorrelogram_metadata
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CrossCorrelogramItem for spike sorting views
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Union
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class CrossCorrelogramItem:
|
|
10
|
+
"""
|
|
11
|
+
Represents a single cross-correlogram between two units
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
*,
|
|
17
|
+
unit_id1: Union[str, int],
|
|
18
|
+
unit_id2: Union[str, int],
|
|
19
|
+
bin_edges_sec: np.ndarray,
|
|
20
|
+
bin_counts: np.ndarray,
|
|
21
|
+
):
|
|
22
|
+
"""
|
|
23
|
+
Initialize a CrossCorrelogramItem
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
unit_id1: Identifier for the first unit
|
|
27
|
+
unit_id2: Identifier for the second unit
|
|
28
|
+
bin_edges_sec: Array of bin edges in seconds
|
|
29
|
+
bin_counts: Array of bin counts
|
|
30
|
+
"""
|
|
31
|
+
self.unit_id1 = unit_id1
|
|
32
|
+
self.unit_id2 = unit_id2
|
|
33
|
+
self.bin_edges_sec = np.array(bin_edges_sec, dtype=np.float32)
|
|
34
|
+
self.bin_counts = np.array(bin_counts, dtype=np.int32)
|
|
35
|
+
|
|
36
|
+
def to_dict(self):
|
|
37
|
+
"""
|
|
38
|
+
Convert the cross-correlogram item to a dictionary representation
|
|
39
|
+
"""
|
|
40
|
+
return {
|
|
41
|
+
"unit_id1": str(self.unit_id1),
|
|
42
|
+
"unit_id2": str(self.unit_id2),
|
|
43
|
+
"bin_edges_sec": self.bin_edges_sec.tolist(),
|
|
44
|
+
"bin_counts": self.bin_counts.tolist(),
|
|
45
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CrossCorrelograms view for figpack - displays multiple cross-correlograms
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import zarr
|
|
6
|
+
import numpy as np
|
|
7
|
+
from typing import List, Optional
|
|
8
|
+
from ...core.figpack_view import FigpackView
|
|
9
|
+
from .CrossCorrelogramItem import CrossCorrelogramItem
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class CrossCorrelograms(FigpackView):
|
|
13
|
+
"""
|
|
14
|
+
A view that displays multiple cross-correlograms for spike sorting analysis
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
*,
|
|
20
|
+
cross_correlograms: List[CrossCorrelogramItem],
|
|
21
|
+
hide_unit_selector: Optional[bool] = False,
|
|
22
|
+
height: Optional[int] = 500,
|
|
23
|
+
):
|
|
24
|
+
"""
|
|
25
|
+
Initialize a CrossCorrelograms view
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
cross_correlograms: List of CrossCorrelogramItem objects
|
|
29
|
+
hide_unit_selector: Whether to hide the unit selector widget
|
|
30
|
+
height: Height of the view in pixels
|
|
31
|
+
"""
|
|
32
|
+
self.cross_correlograms = cross_correlograms
|
|
33
|
+
self.hide_unit_selector = hide_unit_selector
|
|
34
|
+
self.height = height
|
|
35
|
+
|
|
36
|
+
def _write_to_zarr_group(self, group: zarr.Group) -> None:
|
|
37
|
+
"""
|
|
38
|
+
Write the CrossCorrelograms data to a Zarr group
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
group: Zarr group to write data into
|
|
42
|
+
"""
|
|
43
|
+
# Set the view type
|
|
44
|
+
group.attrs["view_type"] = "CrossCorrelograms"
|
|
45
|
+
|
|
46
|
+
# Set view properties
|
|
47
|
+
if self.height is not None:
|
|
48
|
+
group.attrs["height"] = self.height
|
|
49
|
+
if self.hide_unit_selector is not None:
|
|
50
|
+
group.attrs["hide_unit_selector"] = self.hide_unit_selector
|
|
51
|
+
|
|
52
|
+
# Store the number of cross-correlograms
|
|
53
|
+
group.attrs["num_cross_correlograms"] = len(self.cross_correlograms)
|
|
54
|
+
|
|
55
|
+
# Store metadata for each cross-correlogram
|
|
56
|
+
cross_correlogram_metadata = []
|
|
57
|
+
for i, cross_corr in enumerate(self.cross_correlograms):
|
|
58
|
+
cross_corr_name = f"cross_correlogram_{i}"
|
|
59
|
+
|
|
60
|
+
# Store metadata
|
|
61
|
+
metadata = {
|
|
62
|
+
"name": cross_corr_name,
|
|
63
|
+
"unit_id1": str(cross_corr.unit_id1),
|
|
64
|
+
"unit_id2": str(cross_corr.unit_id2),
|
|
65
|
+
"num_bins": len(cross_corr.bin_counts),
|
|
66
|
+
}
|
|
67
|
+
cross_correlogram_metadata.append(metadata)
|
|
68
|
+
|
|
69
|
+
# Create arrays for this cross-correlogram
|
|
70
|
+
group.create_dataset(
|
|
71
|
+
f"{cross_corr_name}/bin_edges_sec",
|
|
72
|
+
data=cross_corr.bin_edges_sec,
|
|
73
|
+
dtype=np.float32,
|
|
74
|
+
)
|
|
75
|
+
group.create_dataset(
|
|
76
|
+
f"{cross_corr_name}/bin_counts",
|
|
77
|
+
data=cross_corr.bin_counts,
|
|
78
|
+
dtype=np.int32,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Store the cross-correlogram metadata
|
|
82
|
+
group.attrs["cross_correlograms"] = cross_correlogram_metadata
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""
|
|
2
|
+
UnitSimilarityScore for spike sorting views
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Union
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class UnitSimilarityScore:
|
|
9
|
+
"""
|
|
10
|
+
Represents a similarity score between two units
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
*,
|
|
16
|
+
unit_id1: Union[str, int],
|
|
17
|
+
unit_id2: Union[str, int],
|
|
18
|
+
similarity: float,
|
|
19
|
+
):
|
|
20
|
+
"""
|
|
21
|
+
Initialize a UnitSimilarityScore
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
unit_id1: Identifier for the first unit
|
|
25
|
+
unit_id2: Identifier for the second unit
|
|
26
|
+
similarity: Similarity score between the units (typically 0-1)
|
|
27
|
+
"""
|
|
28
|
+
self.unit_id1 = unit_id1
|
|
29
|
+
self.unit_id2 = unit_id2
|
|
30
|
+
self.similarity = similarity
|
|
31
|
+
|
|
32
|
+
def to_dict(self):
|
|
33
|
+
"""
|
|
34
|
+
Convert the similarity score to a dictionary representation
|
|
35
|
+
"""
|
|
36
|
+
return {
|
|
37
|
+
"unitId1": self.unit_id1,
|
|
38
|
+
"unitId2": self.unit_id2,
|
|
39
|
+
"similarity": self.similarity,
|
|
40
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""
|
|
2
|
+
UnitsTable view for figpack - displays a table of units with their properties
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import zarr
|
|
6
|
+
import numpy as np
|
|
7
|
+
from typing import List, Optional
|
|
8
|
+
from ...core.figpack_view import FigpackView
|
|
9
|
+
from .UnitsTableColumn import UnitsTableColumn
|
|
10
|
+
from .UnitsTableRow import UnitsTableRow
|
|
11
|
+
from .UnitSimilarityScore import UnitSimilarityScore
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class UnitsTable(FigpackView):
|
|
15
|
+
"""
|
|
16
|
+
A view that displays a table of units with their properties and optional similarity scores
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(
|
|
20
|
+
self,
|
|
21
|
+
*,
|
|
22
|
+
columns: List[UnitsTableColumn],
|
|
23
|
+
rows: List[UnitsTableRow],
|
|
24
|
+
similarity_scores: Optional[List[UnitSimilarityScore]] = None,
|
|
25
|
+
height: Optional[int] = 600,
|
|
26
|
+
):
|
|
27
|
+
"""
|
|
28
|
+
Initialize a UnitsTable view
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
columns: List of UnitsTableColumn objects defining the table structure
|
|
32
|
+
rows: List of UnitsTableRow objects containing the data
|
|
33
|
+
similarity_scores: Optional list of UnitSimilarityScore objects
|
|
34
|
+
height: Height of the view in pixels
|
|
35
|
+
"""
|
|
36
|
+
self.columns = columns
|
|
37
|
+
self.rows = rows
|
|
38
|
+
self.similarity_scores = similarity_scores or []
|
|
39
|
+
self.height = height
|
|
40
|
+
|
|
41
|
+
def _write_to_zarr_group(self, group: zarr.Group) -> None:
|
|
42
|
+
"""
|
|
43
|
+
Write the UnitsTable data to a Zarr group
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
group: Zarr group to write data into
|
|
47
|
+
"""
|
|
48
|
+
# Set the view type
|
|
49
|
+
group.attrs["view_type"] = "UnitsTable"
|
|
50
|
+
|
|
51
|
+
# Set view properties
|
|
52
|
+
if self.height is not None:
|
|
53
|
+
group.attrs["height"] = self.height
|
|
54
|
+
|
|
55
|
+
# Store columns metadata
|
|
56
|
+
columns_metadata = [col.to_dict() for col in self.columns]
|
|
57
|
+
group.attrs["columns"] = columns_metadata
|
|
58
|
+
|
|
59
|
+
# Store rows metadata
|
|
60
|
+
rows_metadata = [row.to_dict() for row in self.rows]
|
|
61
|
+
group.attrs["rows"] = rows_metadata
|
|
62
|
+
|
|
63
|
+
# Store similarity scores if provided
|
|
64
|
+
if self.similarity_scores:
|
|
65
|
+
similarity_scores_metadata = [
|
|
66
|
+
score.to_dict() for score in self.similarity_scores
|
|
67
|
+
]
|
|
68
|
+
group.attrs["similarityScores"] = similarity_scores_metadata
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""
|
|
2
|
+
UnitsTableColumn for spike sorting views
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Literal
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class UnitsTableColumn:
|
|
9
|
+
"""
|
|
10
|
+
Represents a column in a units table
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
*,
|
|
16
|
+
key: str,
|
|
17
|
+
label: str,
|
|
18
|
+
dtype: Literal["int", "float", "str", "bool"],
|
|
19
|
+
):
|
|
20
|
+
"""
|
|
21
|
+
Initialize a UnitsTableColumn
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
key: The key used to access values in the row data
|
|
25
|
+
label: Display label for the column
|
|
26
|
+
dtype: Data type of the column values
|
|
27
|
+
"""
|
|
28
|
+
self.key = key
|
|
29
|
+
self.label = label
|
|
30
|
+
self.dtype = dtype
|
|
31
|
+
|
|
32
|
+
def to_dict(self):
|
|
33
|
+
"""
|
|
34
|
+
Convert the column to a dictionary representation
|
|
35
|
+
"""
|
|
36
|
+
return {
|
|
37
|
+
"key": self.key,
|
|
38
|
+
"label": self.label,
|
|
39
|
+
"dtype": self.dtype,
|
|
40
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""
|
|
2
|
+
UnitsTableRow for spike sorting views
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Union, Dict, Any
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class UnitsTableRow:
|
|
9
|
+
"""
|
|
10
|
+
Represents a row in a units table
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
*,
|
|
16
|
+
unit_id: Union[str, int],
|
|
17
|
+
values: Dict[str, Any],
|
|
18
|
+
):
|
|
19
|
+
"""
|
|
20
|
+
Initialize a UnitsTableRow
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
unit_id: Identifier for the unit
|
|
24
|
+
values: Dictionary of column key to value mappings
|
|
25
|
+
"""
|
|
26
|
+
self.unit_id = unit_id
|
|
27
|
+
self.values = values
|
|
28
|
+
|
|
29
|
+
def to_dict(self):
|
|
30
|
+
"""
|
|
31
|
+
Convert the row to a dictionary representation
|
|
32
|
+
"""
|
|
33
|
+
return {
|
|
34
|
+
"unitId": self.unit_id,
|
|
35
|
+
"values": self.values,
|
|
36
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Spike sorting views for figpack
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from .AutocorrelogramItem import AutocorrelogramItem
|
|
6
|
+
from .Autocorrelograms import Autocorrelograms
|
|
7
|
+
from .CrossCorrelogramItem import CrossCorrelogramItem
|
|
8
|
+
from .CrossCorrelograms import CrossCorrelograms
|
|
9
|
+
from .UnitsTableColumn import UnitsTableColumn
|
|
10
|
+
from .UnitsTableRow import UnitsTableRow
|
|
11
|
+
from .UnitSimilarityScore import UnitSimilarityScore
|
|
12
|
+
from .UnitsTable import UnitsTable
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"AutocorrelogramItem",
|
|
16
|
+
"Autocorrelograms",
|
|
17
|
+
"CrossCorrelogramItem",
|
|
18
|
+
"CrossCorrelograms",
|
|
19
|
+
"UnitsTableColumn",
|
|
20
|
+
"UnitsTableRow",
|
|
21
|
+
"UnitSimilarityScore",
|
|
22
|
+
"UnitsTable",
|
|
23
|
+
]
|
figpack/views/Image.py
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Image view for figpack - displays PNG and JPG images
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import zarr
|
|
6
|
+
import numpy as np
|
|
7
|
+
from typing import Union
|
|
8
|
+
from ..core.figpack_view import FigpackView
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Image(FigpackView):
|
|
12
|
+
"""
|
|
13
|
+
An image visualization component for PNG and JPG files
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, image_path_or_data: Union[str, bytes]):
|
|
17
|
+
"""
|
|
18
|
+
Initialize an Image view
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
image_path_or_data: Path to image file or raw image bytes
|
|
22
|
+
"""
|
|
23
|
+
self.image_path_or_data = image_path_or_data
|
|
24
|
+
|
|
25
|
+
def _write_to_zarr_group(self, group: zarr.Group) -> None:
|
|
26
|
+
"""
|
|
27
|
+
Write the image data to a Zarr group
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
group: Zarr group to write data into
|
|
31
|
+
"""
|
|
32
|
+
# Set the view type
|
|
33
|
+
group.attrs["view_type"] = "Image"
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
# Get the raw image data
|
|
37
|
+
if isinstance(self.image_path_or_data, str):
|
|
38
|
+
# Load from file path
|
|
39
|
+
with open(self.image_path_or_data, "rb") as f:
|
|
40
|
+
image_data = f.read()
|
|
41
|
+
elif isinstance(self.image_path_or_data, bytes):
|
|
42
|
+
# Use bytes directly
|
|
43
|
+
image_data = self.image_path_or_data
|
|
44
|
+
else:
|
|
45
|
+
raise ValueError("image_path_or_data must be a file path or bytes")
|
|
46
|
+
|
|
47
|
+
# Convert bytes to numpy array of uint8
|
|
48
|
+
image_array = np.frombuffer(image_data, dtype=np.uint8)
|
|
49
|
+
|
|
50
|
+
# Store the raw image data as a zarr array
|
|
51
|
+
group.create_dataset(
|
|
52
|
+
"image_data",
|
|
53
|
+
data=image_array,
|
|
54
|
+
dtype=np.uint8,
|
|
55
|
+
chunks=True,
|
|
56
|
+
compressor=zarr.Blosc(
|
|
57
|
+
cname="zstd", clevel=3, shuffle=zarr.Blosc.SHUFFLE
|
|
58
|
+
),
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
# Try to determine format from file signature
|
|
62
|
+
format_type = "Unknown"
|
|
63
|
+
if len(image_data) >= 8:
|
|
64
|
+
# Check PNG signature
|
|
65
|
+
if image_data[:8] == b"\x89PNG\r\n\x1a\n":
|
|
66
|
+
format_type = "PNG"
|
|
67
|
+
# Check JPEG signature
|
|
68
|
+
elif image_data[:2] == b"\xff\xd8":
|
|
69
|
+
format_type = "JPEG"
|
|
70
|
+
|
|
71
|
+
group.attrs["image_format"] = format_type
|
|
72
|
+
group.attrs["data_size"] = len(image_data)
|
|
73
|
+
|
|
74
|
+
except Exception as e:
|
|
75
|
+
# If image loading fails, store error information
|
|
76
|
+
group.attrs["error"] = f"Failed to load image: {str(e)}"
|
|
77
|
+
group.attrs["image_format"] = "Unknown"
|
|
78
|
+
group.attrs["data_size"] = 0
|
|
79
|
+
# Create empty array as placeholder
|
|
80
|
+
group.create_dataset(
|
|
81
|
+
"image_data", data=np.array([], dtype=np.uint8), dtype=np.uint8
|
|
82
|
+
)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Markdown view for figpack - displays markdown content
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import zarr
|
|
6
|
+
from ..core.figpack_view import FigpackView
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Markdown(FigpackView):
|
|
10
|
+
"""
|
|
11
|
+
A markdown content visualization component
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(self, content: str):
|
|
15
|
+
"""
|
|
16
|
+
Initialize a Markdown view
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
content: The markdown content to display
|
|
20
|
+
"""
|
|
21
|
+
self.content = content
|
|
22
|
+
|
|
23
|
+
def _write_to_zarr_group(self, group: zarr.Group) -> None:
|
|
24
|
+
"""
|
|
25
|
+
Write the markdown data to a Zarr group
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
group: Zarr group to write data into
|
|
29
|
+
"""
|
|
30
|
+
# Set the view type
|
|
31
|
+
group.attrs["view_type"] = "Markdown"
|
|
32
|
+
|
|
33
|
+
# Store the markdown content
|
|
34
|
+
group.attrs["content"] = self.content
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MatplotlibFigure view for figpack - displays matplotlib figures
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import zarr
|
|
6
|
+
import io
|
|
7
|
+
from typing import Union, Any
|
|
8
|
+
from ..core.figpack_view import FigpackView
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class MatplotlibFigure(FigpackView):
|
|
12
|
+
"""
|
|
13
|
+
A matplotlib figure visualization component
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, fig):
|
|
17
|
+
"""
|
|
18
|
+
Initialize a MatplotlibFigure view
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
fig: The matplotlib figure object
|
|
22
|
+
"""
|
|
23
|
+
self.fig = fig
|
|
24
|
+
|
|
25
|
+
def _write_to_zarr_group(self, group: zarr.Group) -> None:
|
|
26
|
+
"""
|
|
27
|
+
Write the matplotlib figure data to a Zarr group
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
group: Zarr group to write data into
|
|
31
|
+
"""
|
|
32
|
+
# Set the view type
|
|
33
|
+
group.attrs["view_type"] = "MatplotlibFigure"
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
# Convert matplotlib figure to SVG string
|
|
37
|
+
svg_buffer = io.StringIO()
|
|
38
|
+
self.fig.savefig(
|
|
39
|
+
svg_buffer,
|
|
40
|
+
format="svg",
|
|
41
|
+
bbox_inches="tight",
|
|
42
|
+
facecolor="white",
|
|
43
|
+
edgecolor="none",
|
|
44
|
+
)
|
|
45
|
+
svg_string = svg_buffer.getvalue()
|
|
46
|
+
svg_buffer.close()
|
|
47
|
+
|
|
48
|
+
# Store the SVG data
|
|
49
|
+
group.attrs["svg_data"] = svg_string
|
|
50
|
+
|
|
51
|
+
# Store figure dimensions for reference
|
|
52
|
+
fig_width, fig_height = self.fig.get_size_inches()
|
|
53
|
+
group.attrs["figure_width_inches"] = float(fig_width)
|
|
54
|
+
group.attrs["figure_height_inches"] = float(fig_height)
|
|
55
|
+
|
|
56
|
+
# Store DPI for reference
|
|
57
|
+
group.attrs["figure_dpi"] = float(self.fig.dpi)
|
|
58
|
+
|
|
59
|
+
except Exception as e:
|
|
60
|
+
# If SVG export fails, store error information
|
|
61
|
+
group.attrs["svg_data"] = ""
|
|
62
|
+
group.attrs["error"] = f"Failed to export matplotlib figure: {str(e)}"
|
|
63
|
+
group.attrs["figure_width_inches"] = 6.0
|
|
64
|
+
group.attrs["figure_height_inches"] = 4.0
|
|
65
|
+
group.attrs["figure_dpi"] = 100.0
|