Skip to main content
Glama

louvain

Detect communities in single-cell RNA sequencing data using the Louvain clustering algorithm. Customize resolution, random state, and clustering flavor (vtraag, igraph, RAPIDS) for precise cell grouping.

Instructions

Louvain clustering algorithm for community detection

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
directedNoInterpret the adjacency matrix as directed graph.
flavorNoPackage for computing the clustering: 'vtraag' (default, more powerful), 'igraph' (built-in method), or 'rapids' (GPU accelerated).vtraag
key_addedNoKey under which to add the cluster labels.louvain
neighbors_keyNoUse neighbors connectivities as adjacency. If specified, louvain looks .obsp[.uns[neighbors_key]['connectivities_key']] for connectivities.
obspNoUse .obsp[obsp] as adjacency. You can't specify both `obsp` and `neighbors_key` at the same time.
partition_kwargsNoKey word arguments to pass to partitioning, if 'vtraag' method is being used.
random_stateNoChange the initialization of the optimization.
resolutionNoFor the default flavor ('vtraag') or for 'RAPIDS', you can provide a resolution (higher resolution means finding more and smaller clusters), which defaults to 1.0.
use_weightsNoUse weights from knn graph.

Implementation Reference

  • LouvainModel class defining the input schema and validation for the louvain tool.
    class LouvainModel(JSONParsingModel): """Input schema for the Louvain clustering algorithm.""" resolution: Optional[float] = Field( default=None, description="For the default flavor ('vtraag') or for 'RAPIDS', you can provide a resolution (higher resolution means finding more and smaller clusters), which defaults to 1.0." ) random_state: int = Field( default=0, description="Change the initialization of the optimization." ) key_added: str = Field( default='louvain', description="Key under which to add the cluster labels." ) flavor: Literal['vtraag', 'igraph', 'rapids'] = Field( default='vtraag', description="Package for computing the clustering: 'vtraag' (default, more powerful), 'igraph' (built-in method), or 'rapids' (GPU accelerated)." ) directed: bool = Field( default=True, description="Interpret the adjacency matrix as directed graph." ) use_weights: bool = Field( default=False, description="Use weights from knn graph." ) partition_kwargs: Optional[Dict[str, Any]] = Field( default=None, description="Key word arguments to pass to partitioning, if 'vtraag' method is being used." ) neighbors_key: Optional[str] = Field( default=None, description="Use neighbors connectivities as adjacency. If specified, louvain looks .obsp[.uns[neighbors_key]['connectivities_key']] for connectivities." ) obsp: Optional[str] = Field( default=None, description="Use .obsp[obsp] as adjacency. You can't specify both `obsp` and `neighbors_key` at the same time." ) @field_validator('resolution') def validate_resolution(cls, v: Optional[float]) -> Optional[float]: """Validate resolution is positive if provided""" if v is not None and v <= 0: raise ValueError("resolution must be a positive number") return v @field_validator('obsp', 'neighbors_key') def validate_graph_source(cls, v: Optional[str], info: ValidationInfo) -> Optional[str]: """Validate that obsp and neighbors_key are not both specified""" values = info.data if v is not None and 'obsp' in values and 'neighbors_key' in values: if values['obsp'] is not None and values['neighbors_key'] is not None: raise ValueError("Cannot specify both obsp and neighbors_key") return v @field_validator('flavor') def validate_flavor(cls, v: str) -> str: """Validate flavor is supported""" if v not in ['vtraag', 'igraph', 'rapids']: raise ValueError("flavor must be one of 'vtraag', 'igraph', or 'rapids'") return v
  • Registration of the 'louvain' MCP Tool object, specifying name, description, and input schema.
    # Add louvain tool louvain_tool = types.Tool( name="louvain", description="Louvain clustering algorithm for community detection", inputSchema=LouvainModel.model_json_schema(), )
  • Mapping of 'louvain' to sc.tl.louvain function for dispatch in tool execution.
    tl_func = { "tsne": sc.tl.tsne, "umap": sc.tl.umap, "draw_graph": sc.tl.draw_graph, "diffmap": sc.tl.diffmap, "embedding_density": sc.tl.embedding_density, "leiden": sc.tl.leiden, "louvain": sc.tl.louvain, "dendrogram": sc.tl.dendrogram, "dpt": sc.tl.dpt, "paga": sc.tl.paga, "ingest": sc.tl.ingest, "rank_genes_groups": sc.tl.rank_genes_groups, "filter_rank_genes_groups": sc.tl.filter_rank_genes_groups, "marker_gene_overlap": sc.tl.marker_gene_overlap, "score_genes": sc.tl.score_genes, "score_genes_cell_cycle": sc.tl.score_genes_cell_cycle, }
  • Registration of louvain_tool in the tl_tools dictionary, likely used for MCP server tool list.
    tl_tools = { "tsne": tsne_tool, "umap": umap_tool, "draw_graph": draw_graph_tool, "diffmap": diffmap_tool, "embedding_density": embedding_density_tool, "leiden": leiden_tool, "louvain": louvain_tool, "dendrogram": dendrogram_tool, "dpt": dpt_tool, "paga": paga_tool, "ingest": ingest_tool, "rank_genes_groups": rank_genes_groups_tool, "filter_rank_genes_groups": filter_rank_genes_groups_tool, "marker_gene_overlap": marker_gene_overlap_tool, "score_genes": score_genes_tool, "score_genes_cell_cycle": score_genes_cell_cycle_tool, }
  • Handler function that executes the tool by dispatching to sc.tl.louvain based on func='louvain', handling arguments and logging.
    def run_tl_func(ads, func, arguments): adata = ads.adata_dic[ads.active] if func not in tl_func: raise ValueError(f"Unsupported function: {func}") run_func = tl_func[func] parameters = inspect.signature(run_func).parameters kwargs = {k: arguments.get(k) for k in parameters if k in arguments} try: res = run_func(adata, **kwargs) add_op_log(adata, run_func, kwargs) except Exception as e: logger.error(f"Error running function {func}: {e}") raise return

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/huang-sh/scmcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server