scmcp-shared 0.2.0__py3-none-any.whl → 0.3.0__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.
- scmcp_shared/__init__.py +1 -1
- scmcp_shared/cli.py +96 -0
- scmcp_shared/schema/__init__.py +22 -1
- scmcp_shared/schema/io.py +4 -8
- scmcp_shared/schema/pl.py +2 -3
- scmcp_shared/schema/pp.py +15 -15
- scmcp_shared/schema/tl.py +18 -24
- scmcp_shared/schema/util.py +11 -11
- scmcp_shared/server/__init__.py +11 -49
- scmcp_shared/server/base.py +153 -0
- scmcp_shared/server/io.py +71 -61
- scmcp_shared/server/pl.py +288 -294
- scmcp_shared/server/pp.py +320 -358
- scmcp_shared/server/tl.py +393 -402
- scmcp_shared/server/util.py +241 -240
- scmcp_shared/util.py +110 -43
- {scmcp_shared-0.2.0.dist-info → scmcp_shared-0.3.0.dist-info}/METADATA +1 -1
- scmcp_shared-0.3.0.dist-info/RECORD +21 -0
- scmcp_shared/schema/base.py +0 -11
- scmcp_shared-0.2.0.dist-info/RECORD +0 -20
- {scmcp_shared-0.2.0.dist-info → scmcp_shared-0.3.0.dist-info}/WHEEL +0 -0
- {scmcp_shared-0.2.0.dist-info → scmcp_shared-0.3.0.dist-info}/licenses/LICENSE +0 -0
scmcp_shared/server/pl.py
CHANGED
@@ -3,319 +3,313 @@ import inspect
|
|
3
3
|
from functools import partial
|
4
4
|
import scanpy as sc
|
5
5
|
from fastmcp import FastMCP, Context
|
6
|
+
from fastmcp.exceptions import ToolError
|
6
7
|
from ..schema.pl import *
|
8
|
+
from ..schema import AdataInfo
|
7
9
|
from pathlib import Path
|
8
|
-
from ..logging_config import setup_logger
|
9
10
|
from ..util import forward_request, sc_like_plot, get_ads
|
11
|
+
from .base import BaseMCP
|
10
12
|
|
11
13
|
|
12
|
-
|
14
|
+
class ScanpyPlottingMCP(BaseMCP):
|
15
|
+
def __init__(self, include_tools: list = None, exclude_tools: list = None, AdataInfo: AdataInfo = AdataInfo):
|
16
|
+
"""
|
17
|
+
Initialize ScanpyPreprocessingMCP with optional tool filtering.
|
18
|
+
|
19
|
+
Args:
|
20
|
+
include_tools (list, optional): List of tool names to include. If None, all tools are included.
|
21
|
+
exclude_tools (list, optional): List of tool names to exclude. If None, no tools are excluded.
|
22
|
+
AdataInfo: The AdataInfo class to use for type annotations.
|
23
|
+
"""
|
24
|
+
super().__init__("ScanpyMCP-PL-Server", include_tools, exclude_tools, AdataInfo)
|
13
25
|
|
14
|
-
|
26
|
+
def _tool_pca(self):
|
27
|
+
def _pca(request: PCAModel, adinfo: self.AdataInfo=self.AdataInfo()):
|
28
|
+
"""Scatter plot in PCA coordinates. default figure for PCA plot"""
|
29
|
+
try:
|
30
|
+
if (res := forward_request("pl_pca", request, adinfo)) is not None:
|
31
|
+
return res
|
32
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
33
|
+
fig_path = sc_like_plot(sc.pl.pca, adata, request, adinfo)
|
34
|
+
return {"figpath": fig_path}
|
35
|
+
except ToolError as e:
|
36
|
+
raise ToolError(e)
|
37
|
+
except Exception as e:
|
38
|
+
if hasattr(e, '__context__') and e.__context__:
|
39
|
+
raise ToolError(e.__context__)
|
40
|
+
else:
|
41
|
+
raise ToolError(e)
|
42
|
+
return _pca
|
15
43
|
|
44
|
+
def _tool_diffmap(self):
|
45
|
+
def _diffmap(request: DiffusionMapModel, adinfo: self.AdataInfo=self.AdataInfo()):
|
46
|
+
"""Plot diffusion map embedding of cells."""
|
47
|
+
try:
|
48
|
+
if (res := forward_request("pl_diffmap", request, adinfo)) is not None:
|
49
|
+
return res
|
50
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
51
|
+
fig_path = sc_like_plot(sc.pl.diffmap, adata, request, adinfo)
|
52
|
+
return {"figpath": fig_path}
|
53
|
+
except ToolError as e:
|
54
|
+
raise ToolError(e)
|
55
|
+
except Exception as e:
|
56
|
+
if hasattr(e, '__context__') and e.__context__:
|
57
|
+
raise ToolError(e.__context__)
|
58
|
+
else:
|
59
|
+
raise ToolError(e)
|
60
|
+
return _diffmap
|
16
61
|
|
62
|
+
def _tool_violin(self):
|
63
|
+
def _violin(request: ViolinModel, adinfo: self.AdataInfo=self.AdataInfo()):
|
64
|
+
"""Plot violin plot of one or more variables."""
|
65
|
+
try:
|
66
|
+
if (res := forward_request("pl_violin", request, adinfo)) is not None:
|
67
|
+
return res
|
68
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
69
|
+
fig_path = sc_like_plot(sc.pl.violin, adata, request, adinfo)
|
70
|
+
return {"figpath": fig_path}
|
71
|
+
except KeyError as e:
|
72
|
+
raise ToolError(f"doest found {e} in current sampleid with adtype {adinfo.adtype}")
|
73
|
+
except ToolError as e:
|
74
|
+
raise ToolError(e)
|
75
|
+
except Exception as e:
|
76
|
+
if hasattr(e, '__context__') and e.__context__:
|
77
|
+
raise ToolError(e.__context__)
|
78
|
+
else:
|
79
|
+
raise ToolError(e)
|
80
|
+
return _violin
|
17
81
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
82
|
+
def _tool_stacked_violin(self):
|
83
|
+
def _stacked_violin(request: StackedViolinModel, adinfo: self.AdataInfo=self.AdataInfo()):
|
84
|
+
"""Plot stacked violin plots. Makes a compact image composed of individual violin plots stacked on top of each other."""
|
85
|
+
try:
|
86
|
+
if (res := forward_request("pl_stacked_violin", request, adinfo)) is not None:
|
87
|
+
return res
|
88
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
89
|
+
fig_path = sc_like_plot(sc.pl.stacked_violin, adata, request, adinfo)
|
90
|
+
return {"figpath": fig_path}
|
91
|
+
except ToolError as e:
|
92
|
+
raise ToolError(e)
|
93
|
+
except Exception as e:
|
94
|
+
if hasattr(e, '__context__') and e.__context__:
|
95
|
+
raise ToolError(e.__context__)
|
96
|
+
else:
|
97
|
+
raise ToolError(e)
|
98
|
+
return _stacked_violin
|
35
99
|
|
36
|
-
|
37
|
-
async def
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
100
|
+
def _tool_heatmap(self):
|
101
|
+
async def _heatmap(request: HeatmapModel, adinfo: self.AdataInfo=self.AdataInfo()):
|
102
|
+
"""Heatmap of the expression values of genes."""
|
103
|
+
try:
|
104
|
+
if (res := forward_request("pl_heatmap", request, adinfo)) is not None:
|
105
|
+
return res
|
106
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
107
|
+
fig_path = sc_like_plot(sc.pl.heatmap, adata, request, adinfo)
|
108
|
+
return {"figpath": fig_path}
|
109
|
+
except ToolError as e:
|
110
|
+
raise ToolError(e)
|
111
|
+
except Exception as e:
|
112
|
+
if hasattr(e, '__context__') and e.__context__:
|
113
|
+
raise ToolError(e.__context__)
|
114
|
+
else:
|
115
|
+
raise ToolError(e)
|
116
|
+
return _heatmap
|
53
117
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
118
|
+
def _tool_dotplot(self):
|
119
|
+
def _dotplot(request: DotplotModel, adinfo: self.AdataInfo=self.AdataInfo()):
|
120
|
+
"""Plot dot plot of expression values per gene for each group."""
|
121
|
+
try:
|
122
|
+
if (res := forward_request("pl_dotplot", request, adinfo)) is not None:
|
123
|
+
return res
|
124
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
125
|
+
fig_path = sc_like_plot(sc.pl.dotplot, adata, request, adinfo)
|
126
|
+
return {"figpath": fig_path}
|
127
|
+
except ToolError as e:
|
128
|
+
raise ToolError(e)
|
129
|
+
except Exception as e:
|
130
|
+
if hasattr(e, '__context__') and e.__context__:
|
131
|
+
raise ToolError(e.__context__)
|
132
|
+
else:
|
133
|
+
raise ToolError(e)
|
134
|
+
return _dotplot
|
71
135
|
|
136
|
+
def _tool_matrixplot(self):
|
137
|
+
def _matrixplot(request: MatrixplotModel, adinfo: self.AdataInfo=self.AdataInfo()):
|
138
|
+
"""matrixplot, Create a heatmap of the mean expression values per group of each var_names."""
|
139
|
+
try:
|
140
|
+
if (res := forward_request("pl_matrixplot", request, adinfo)) is not None:
|
141
|
+
return res
|
142
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
143
|
+
fig_path = sc_like_plot(sc.pl.matrixplot, adata, request, adinfo)
|
144
|
+
return {"figpath": fig_path}
|
145
|
+
except ToolError as e:
|
146
|
+
raise ToolError(e)
|
147
|
+
except Exception as e:
|
148
|
+
if hasattr(e, '__context__') and e.__context__:
|
149
|
+
raise ToolError(e.__context__)
|
150
|
+
else:
|
151
|
+
raise ToolError(e)
|
152
|
+
return _matrixplot
|
72
153
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
154
|
+
def _tool_tracksplot(self):
|
155
|
+
def _tracksplot(request: TracksplotModel, adinfo: self.AdataInfo=self.AdataInfo()):
|
156
|
+
"""tracksplot, compact plot of expression of a list of genes."""
|
157
|
+
try:
|
158
|
+
if (res := forward_request("pl_tracksplot", request, adinfo)) is not None:
|
159
|
+
return res
|
160
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
161
|
+
fig_path = sc_like_plot(sc.pl.tracksplot, adata, request, adinfo)
|
162
|
+
return {"figpath": fig_path}
|
163
|
+
except ToolError as e:
|
164
|
+
raise ToolError(e)
|
165
|
+
except Exception as e:
|
166
|
+
if hasattr(e, '__context__') and e.__context__:
|
167
|
+
raise ToolError(e.__context__)
|
168
|
+
else:
|
169
|
+
raise ToolError(e)
|
170
|
+
return _tracksplot
|
90
171
|
|
172
|
+
def _tool_scatter(self):
|
173
|
+
def _scatter(request: EnhancedScatterModel, adinfo: self.AdataInfo=self.AdataInfo()):
|
174
|
+
"""Plot a scatter plot of two variables, Scatter plot along observations or variables axes."""
|
175
|
+
try:
|
176
|
+
if (res := forward_request("pl_scatter", request, adinfo)) is not None:
|
177
|
+
return res
|
178
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
179
|
+
fig_path = sc_like_plot(sc.pl.scatter, adata, request, adinfo)
|
180
|
+
return {"figpath": fig_path}
|
181
|
+
except ToolError as e:
|
182
|
+
raise ToolError(e)
|
183
|
+
except Exception as e:
|
184
|
+
if hasattr(e, '__context__') and e.__context__:
|
185
|
+
raise ToolError(e.__context__)
|
186
|
+
else:
|
187
|
+
raise ToolError(e)
|
188
|
+
return _scatter
|
91
189
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
190
|
+
def _tool_embedding(self):
|
191
|
+
def _embedding(request: EmbeddingModel, adinfo: self.AdataInfo=self.AdataInfo()):
|
192
|
+
"""Scatter plot for user specified embedding basis (e.g. umap, tsne, etc)."""
|
193
|
+
try:
|
194
|
+
if (res := forward_request("pl_embedding", request, adinfo)) is not None:
|
195
|
+
return res
|
196
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
197
|
+
fig_path = sc_like_plot(sc.pl.embedding, adata, request, adinfo)
|
198
|
+
return {"figpath": fig_path}
|
199
|
+
except KeyError as e:
|
200
|
+
raise ToolError(f"doest found {e} in current sampleid with adtype {adinfo.adtype}")
|
201
|
+
except Exception as e:
|
202
|
+
if hasattr(e, '__context__') and e.__context__:
|
203
|
+
raise ToolError(e.__context__)
|
204
|
+
else:
|
205
|
+
raise ToolError(e)
|
206
|
+
return _embedding
|
109
207
|
|
208
|
+
def _tool_embedding_density(self):
|
209
|
+
def _embedding_density(request: EmbeddingDensityModel, adinfo: self.AdataInfo=self.AdataInfo()):
|
210
|
+
"""Plot the density of cells in an embedding."""
|
211
|
+
try:
|
212
|
+
if (res := forward_request("pl_embedding_density", request, adinfo)) is not None:
|
213
|
+
return res
|
214
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
215
|
+
fig_path = sc_like_plot(sc.pl.embedding_density, adata, request, adinfo)
|
216
|
+
return {"figpath": fig_path}
|
217
|
+
except ToolError as e:
|
218
|
+
raise ToolError(e)
|
219
|
+
except Exception as e:
|
220
|
+
if hasattr(e, '__context__') and e.__context__:
|
221
|
+
raise ToolError(e.__context__)
|
222
|
+
else:
|
223
|
+
raise ToolError(e)
|
224
|
+
return _embedding_density
|
110
225
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
226
|
+
def _tool_rank_genes_groups(self):
|
227
|
+
def _rank_genes_groups(request: RankGenesGroupsModel, adinfo: self.AdataInfo=self.AdataInfo()):
|
228
|
+
"""Plot ranking of genes based on differential expression."""
|
229
|
+
try:
|
230
|
+
if (res := forward_request("pl_rank_genes_groups", request, adinfo)) is not None:
|
231
|
+
return res
|
232
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
233
|
+
fig_path = sc_like_plot(sc.pl.rank_genes_groups, adata, request, adinfo)
|
234
|
+
return {"figpath": fig_path}
|
235
|
+
except ToolError as e:
|
236
|
+
raise ToolError(e)
|
237
|
+
except Exception as e:
|
238
|
+
if hasattr(e, '__context__') and e.__context__:
|
239
|
+
raise ToolError(e.__context__)
|
240
|
+
else:
|
241
|
+
raise ToolError(e)
|
242
|
+
return _rank_genes_groups
|
128
243
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
244
|
+
def _tool_rank_genes_groups_dotplot(self):
|
245
|
+
def _rank_genes_groups_dotplot(request: RankGenesGroupsDotplotModel, adinfo: self.AdataInfo=self.AdataInfo()):
|
246
|
+
"""Plot ranking of genes(DEGs) using dotplot visualization. Defualt plot DEGs for rank_genes_groups tool"""
|
247
|
+
try:
|
248
|
+
if (res := forward_request("pl_rank_genes_groups_dotplot", request, adinfo)) is not None:
|
249
|
+
return res
|
250
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
251
|
+
fig_path = sc_like_plot(sc.pl.rank_genes_groups_dotplot, adata, request, adinfo)
|
252
|
+
return {"figpath": fig_path}
|
253
|
+
except ToolError as e:
|
254
|
+
raise ToolError(e)
|
255
|
+
except Exception as e:
|
256
|
+
if hasattr(e, '__context__') and e.__context__:
|
257
|
+
raise ToolError(e.__context__)
|
258
|
+
else:
|
259
|
+
raise ToolError(e)
|
260
|
+
return _rank_genes_groups_dotplot
|
146
261
|
|
262
|
+
def _tool_clustermap(self):
|
263
|
+
def _clustermap(request: ClusterMapModel, adinfo: self.AdataInfo=self.AdataInfo()):
|
264
|
+
"""Plot hierarchical clustering of cells and genes."""
|
265
|
+
try:
|
266
|
+
if (res := forward_request("pl_clustermap", request, adinfo)) is not None:
|
267
|
+
return res
|
268
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
269
|
+
fig_path = sc_like_plot(sc.pl.clustermap, adata, request, adinfo)
|
270
|
+
return {"figpath": fig_path}
|
271
|
+
except ToolError as e:
|
272
|
+
raise ToolError(e)
|
273
|
+
except Exception as e:
|
274
|
+
if hasattr(e, '__context__') and e.__context__:
|
275
|
+
raise ToolError(e.__context__)
|
276
|
+
else:
|
277
|
+
raise ToolError(e)
|
278
|
+
return _clustermap
|
147
279
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
280
|
+
def _tool_highly_variable_genes(self):
|
281
|
+
def _highly_variable_genes(request: HighlyVariableGenesModel, adinfo: self.AdataInfo=self.AdataInfo()):
|
282
|
+
"""plot highly variable genes; Plot dispersions or normalized variance versus means for genes."""
|
283
|
+
try:
|
284
|
+
if (res := forward_request("pl_highly_variable_genes", request, adinfo)) is not None:
|
285
|
+
return res
|
286
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
287
|
+
fig_path = sc_like_plot(sc.pl.highly_variable_genes, adata, request, adinfo)
|
288
|
+
return {"figpath": fig_path}
|
289
|
+
except ToolError as e:
|
290
|
+
raise ToolError(e)
|
291
|
+
except Exception as e:
|
292
|
+
if hasattr(e, '__context__') and e.__context__:
|
293
|
+
raise ToolError(e.__context__)
|
294
|
+
else:
|
295
|
+
raise ToolError(e)
|
296
|
+
return _highly_variable_genes
|
165
297
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
298
|
+
def _tool_pca_variance_ratio(self):
|
299
|
+
def _pca_variance_ratio(request: PCAVarianceRatioModel, adinfo: self.AdataInfo=self.AdataInfo()):
|
300
|
+
"""Plot the PCA variance ratio to visualize explained variance."""
|
301
|
+
try:
|
302
|
+
if (res := forward_request("pl_pca_variance_ratio", request, adinfo)) is not None:
|
303
|
+
return res
|
304
|
+
adata = get_ads().get_adata(adinfo=adinfo)
|
305
|
+
fig_path = sc_like_plot(sc.pl.pca_variance_ratio, adata, request, adinfo)
|
306
|
+
return {"figpath": fig_path}
|
307
|
+
except ToolError as e:
|
308
|
+
raise ToolError(e)
|
309
|
+
except Exception as e:
|
310
|
+
if hasattr(e, '__context__') and e.__context__:
|
311
|
+
raise ToolError(e.__context__)
|
312
|
+
else:
|
313
|
+
raise ToolError(e)
|
314
|
+
return _pca_variance_ratio
|
183
315
|
|
184
|
-
@pl_mcp.tool()
|
185
|
-
async def embedding(request: EmbeddingModel):
|
186
|
-
"""Scatter plot for user specified embedding basis (e.g. umap, tsne, etc)."""
|
187
|
-
try:
|
188
|
-
result = await forward_request("pl_embedding", request)
|
189
|
-
if result is not None:
|
190
|
-
return result
|
191
|
-
adata = get_ads().get_adata(request=request)
|
192
|
-
fig_path = sc_like_plot(sc.pl.embedding, adata, request)
|
193
|
-
return {"figpath": fig_path}
|
194
|
-
except KeyError as e:
|
195
|
-
from fastmcp.exceptions import ToolError
|
196
|
-
raise ToolError(f"doest found {e} in current sampleid with adtype {request.adtype}")
|
197
|
-
except Exception as e:
|
198
|
-
if hasattr(e, '__context__') and e.__context__:
|
199
|
-
raise Exception(f"{str(e.__context__)}")
|
200
|
-
else:
|
201
|
-
raise e
|
202
|
-
|
203
|
-
|
204
|
-
@pl_mcp.tool()
|
205
|
-
async def embedding_density(request: EmbeddingDensityModel):
|
206
|
-
"""Plot the density of cells in an embedding."""
|
207
|
-
try:
|
208
|
-
result = await forward_request("pl_embedding_density", request)
|
209
|
-
if result is not None:
|
210
|
-
return result
|
211
|
-
adata = get_ads().get_adata(request=request)
|
212
|
-
fig_path = sc_like_plot(sc.pl.embedding_density, adata, request)
|
213
|
-
return {"figpath": fig_path}
|
214
|
-
except KeyError as e:
|
215
|
-
raise e
|
216
|
-
except Exception as e:
|
217
|
-
if hasattr(e, '__context__') and e.__context__:
|
218
|
-
raise Exception(f"{str(e.__context__)}")
|
219
|
-
else:
|
220
|
-
raise e
|
221
|
-
|
222
|
-
@pl_mcp.tool()
|
223
|
-
async def rank_genes_groups(request: RankGenesGroupsModel):
|
224
|
-
"""Plot ranking of genes based on differential expression."""
|
225
|
-
try:
|
226
|
-
result = await forward_request("pl_rank_genes_groups", request)
|
227
|
-
if result is not None:
|
228
|
-
return result
|
229
|
-
adata = get_ads().get_adata(request=request)
|
230
|
-
fig_path = sc_like_plot(sc.pl.rank_genes_groups, adata, request)
|
231
|
-
return {"figpath": fig_path}
|
232
|
-
except KeyError as e:
|
233
|
-
raise e
|
234
|
-
except Exception as e:
|
235
|
-
if hasattr(e, '__context__') and e.__context__:
|
236
|
-
raise Exception(f"{str(e.__context__)}")
|
237
|
-
else:
|
238
|
-
raise e
|
239
|
-
|
240
|
-
|
241
|
-
@pl_mcp.tool()
|
242
|
-
async def rank_genes_groups_dotplot(
|
243
|
-
request: RankGenesGroupsDotplotModel,
|
244
|
-
):
|
245
|
-
"""Plot ranking of genes(DEGs) using dotplot visualization. Defualt plot DEGs for rank_genes_groups tool"""
|
246
|
-
try:
|
247
|
-
result = await forward_request("pl_rank_genes_groups_dotplot", request)
|
248
|
-
if result is not None:
|
249
|
-
return result
|
250
|
-
adata = get_ads().get_adata(request=request)
|
251
|
-
fig_path = sc_like_plot(sc.pl.rank_genes_groups_dotplot, adata, request)
|
252
|
-
return {"figpath": fig_path}
|
253
|
-
except KeyError as e:
|
254
|
-
raise e
|
255
|
-
except Exception as e:
|
256
|
-
if hasattr(e, '__context__') and e.__context__:
|
257
|
-
raise Exception(f"{str(e.__context__)}")
|
258
|
-
else:
|
259
|
-
raise e
|
260
|
-
|
261
|
-
|
262
|
-
@pl_mcp.tool()
|
263
|
-
async def clustermap(
|
264
|
-
request: ClusterMapModel = ClusterMapModel()
|
265
|
-
):
|
266
|
-
"""Plot hierarchical clustering of cells and genes."""
|
267
|
-
try:
|
268
|
-
result = await forward_request("pl_clustermap", request)
|
269
|
-
if result is not None:
|
270
|
-
return result
|
271
|
-
adata = get_ads().get_adata(request=request)
|
272
|
-
fig_path = sc_like_plot(sc.pl.clustermap, adata, request)
|
273
|
-
return {"figpath": fig_path}
|
274
|
-
except KeyError as e:
|
275
|
-
raise e
|
276
|
-
except Exception as e:
|
277
|
-
if hasattr(e, '__context__') and e.__context__:
|
278
|
-
raise Exception(f"{str(e.__context__)}")
|
279
|
-
else:
|
280
|
-
raise e
|
281
|
-
|
282
|
-
@pl_mcp.tool()
|
283
|
-
async def highly_variable_genes(
|
284
|
-
request: HighlyVariableGenesModel = HighlyVariableGenesModel()
|
285
|
-
):
|
286
|
-
"""plot highly variable genes; Plot dispersions or normalized variance versus means for genes."""
|
287
|
-
try:
|
288
|
-
result = await forward_request("pl_highly_variable_genes", request)
|
289
|
-
if result is not None:
|
290
|
-
return result
|
291
|
-
adata = get_ads().get_adata(request=request)
|
292
|
-
fig_path = sc_like_plot(sc.pl.highly_variable_genes, adata, request)
|
293
|
-
return {"figpath": fig_path}
|
294
|
-
except KeyError as e:
|
295
|
-
raise e
|
296
|
-
except Exception as e:
|
297
|
-
if hasattr(e, '__context__') and e.__context__:
|
298
|
-
raise Exception(f"{str(e.__context__)}")
|
299
|
-
else:
|
300
|
-
raise e
|
301
|
-
|
302
|
-
|
303
|
-
@pl_mcp.tool()
|
304
|
-
async def pca_variance_ratio(
|
305
|
-
request: PCAVarianceRatioModel = PCAVarianceRatioModel()
|
306
|
-
):
|
307
|
-
"""Plot the PCA variance ratio to visualize explained variance."""
|
308
|
-
try:
|
309
|
-
result = await forward_request("pl_pca_variance_ratio", request)
|
310
|
-
if result is not None:
|
311
|
-
return result
|
312
|
-
adata = get_ads().get_adata(request=request)
|
313
|
-
fig_path = sc_like_plot(sc.pl.pca_variance_ratio, adata, request)
|
314
|
-
return {"figpath": fig_path}
|
315
|
-
except KeyError as e:
|
316
|
-
raise e
|
317
|
-
except Exception as e:
|
318
|
-
if hasattr(e, '__context__') and e.__context__:
|
319
|
-
raise Exception(f"{str(e.__context__)}")
|
320
|
-
else:
|
321
|
-
raise e
|