Skip to content

2 SpacePath as library

Johanna G.R.L edited this page Oct 15, 2026 · 3 revisions

How to use the SpacePath.core library

SpacePath can also be used as a Python library πŸ“¦, requiring knowledge of Python scripting from the user. This flexibility allows seamless articulation of SpacePath with external popular spatial omics packages (e.g., squidpy) for advanced user-defined analyses.

Once SpacePath is installed and ready for use, the library can be imported directly into scripts, Jupyter notebooks, or other Python environments, for example:

import SpacePath.core.method as spm

Recommended folder structure

The recommended folder structure mirrors the command-line usage. The same provided example data is used for demonstration:

$working_dir 
β”œβ”€β”€ examples-sm-data  # downloaded example data
β”‚    β”œβ”€β”€ ...
β”œβ”€β”€ SpacePath/    # clone (optional), DO NOT modify anything here
β”‚       
β”œβ”€β”€ my_scripts/    # HERE your .py scripts or jupyter notebooks
β”‚    β”œβ”€β”€ script_1.py      # first script 
β”‚    β”œβ”€β”€ notebook1.ipynb    
β”‚    β”œβ”€β”€ ...

Such custom scripts folder, e.g. my_scripts/, must always be created outside the data folder, and also outside the cloned repository (if present).

A last verification before using SpacePath.core

If you have not yet installed the library, follow the instructions of installation as shown its README. Once installed, load it from your terminal:

conda activate spacepath

in your first .py script (or jupyter notebook) within your folder my_scripts, verify the import:

import SpacePath.core.data as spd

You’re now ready to use the library! The next section provides code snippets for a standard analysis with SpacePath.core using the provided example data.

Snippets showcasing SpacePath.core on the example data

We analyze here the publicly available data of the spatial lipidome of the transversal section of the root of a corn plant. The following snippets must be used in Python scripts (or notebooks).

Import dependencies first

import os
import pandas as pd
import numpy as np
import pandas as pd
import anndata as ad
import squidpy as sq
import matplotlib.pyplot as plt

Define the variables of recurrent use

data_centralized_folder = "../examples-sm-data"
figures_centralized_folder = "../examples-figures"
SAMPLE = "example-corn-root"
subfolder = SAMPLE
plot_folder = os.path.join(figures_centralized_folder, SAMPLE)

Data and annotations pretreatment

Normalize, perform QC and save updated intensities. This produces an updated anndata object with all the new results (of our computations) inside

import SpacePath.core.processing.measures_methods as measures_methods
import SpacePath.core.data as spd
import SpacePath.core.method as spm

# m/z intensities matrix and metadata in the form of anndata object
adata_mz = ad.read_h5ad(filename=os.path.join(
        data_centralized_folder, subfolder, f'{SAMPLE}.h5ad'))

# load annotations with SpacePath.core library   
annots_obj = spd.MetabolomeAnnotations(
            name=SAMPLE, data_dir=data_centralized_folder,
            subfolder=subfolder, 
            annotation_files={'LipidMaps': f"{SAMPLE}-LipidMaps.csv",
                              'HMDB': f"{SAMPLE}-HMDB.csv"})

annots_obj.load()   

# synchronize objects 
annots_obj, adata_mz = measures_methods.match_adata_mz_and_annots(annots_obj, adata_mz)

adata_mz = spm.NormalizeIntensities.run(adata_mz)  #

updated_config = spm.ClassifyMZProtocolConfig(
    msm_cutoff=0.2, 
    offSample_cutoff=0.3,
    fdr_cutoff=0.5,  #  0.2 is recommended but this data has few features
    moran_I_cutoff=0.08,
    moran_padj_cutoff=0.1   # we recommend 0.05, but this data has few features
)

adata_mz = spm.ClassifyMZProtocol.run(
    adata_mz, annots_obj, SAMPLE, plot_folder, 
    config=updated_config)

Now clean anndata and re-synchronize with annotations

adata_mz = adata_mz[:,
    adata_mz.var.loc[adata_mz.var['final_quality'] == "good",
    "mz"].astype(str).tolist()]

annots_obj, adata_mz = measures_methods.match_adata_mz_and_annots(
    annots_obj, adata_mz)

Per-spot pathways scoring for the spatial data

We can now compute pathway scores: the sspa library provides wrappers for this and is used by SpacePath.core. Here we use KEGG pathways as reference, for demonstration. Note that Wikipathways are also supported, check the end of this section.

  1. Load the object required to translate annotations to KEGG ids (we also provide the required files)
ref_KEGG_ids_obj = spd.MetaboliteIdsMappings(
    data_dir=data_centralized_folder,
    subfolder="metabolites-mappings",
    mapping_files={'HMDB': "HMDB-to-KEGG_05-07-24.tsv",
                   'LipidMaps': "LipidMaps-to-KEGG_10-18-24.tsv",
                   'CoreMetabolome': "CoreMetabolome-to-KEGG_05-07-24.tsv"})
ref_KEGG_ids_obj.load()

use it to translate provided annotations

# Create a working copy for KEGG conversion
annots_current = annots_obj.model_copy()
# then do the KEGG conversion plus cleaning-up: 
annots_current.usable_id = "KEGG"
annots_current.convert_ids_to_kegg(ref_KEGG_ids_obj.table)
annots_current.keep_best_mz_id_pairs(adata_mz.var.copy())
annots_current.remove_redundant_aliases()
annots_current.df.head()
  1. load reference metabolic pathways
pathways_files_location_info = {
        "KEGG" : {'file': "KEGG_hsa_pathways_compounds_R110.gmt",
                      'subfolder': "metabolites-mappings",
                      'id_type': 'KEGG'},
        "WIKI" : {'file': "WIKIPATHWAYS_human_multi_id_redundant.mmt",
                          'subfolder': "metabolites-mappings",
                          'id_type': 'moleculeIds'}}

sets_KEGG = spd.MetabolicPathways(
    data_dir=data_centralized_folder,
     subfolder=pathways_files_location_info['KEGG']['subfolder'],
    file=pathways_files_location_info['KEGG']['file'])

sets_KEGG.molecule_id_type = "KEGG"
sets_KEGG.load()
  1. compute the scores: a matrix of of probabilistic weights of compound IDs per spot is computed on the process:
sets_KEGG, annots_current.df = spm.SyncPathwaysAndAnnots.run(
            sets_KEGG.model_copy(),
            annots_current.df,
            usable_id=pathways_files_location_info['KEGG']['id_type'],
            min_set_size=2, max_set_size=100)

# metabolites weights matrix :
metabolites_computed_df, coords = spm.ComputeAssignmentsWeights.run(
            adata_mz, annots_current.df,
            usable_id=pathways_files_location_info['KEGG']['id_type'])
config_run_scores = spm.ComputePathwaysScoresConfig(
    type_abbr="KEGG", min_entity=2)

kegg_scores_df = spm.ComputePathwaysScores.run(
    sets_KEGG.to_dict(),
    metabolites_computed_df,
    config=config_run_scores
)

The kegg_scores_df dataframe contains the scores per spot of each pathway. With our parameter (min_set_size=2) the scores are only computed for pathways represented by at least 2 different compound IDs, which in turn represent at least 2 different $m/z$.

There is more!

The pathways coverage is reported to be low in metabolomics, and extremely low in lipidomics profiles. In view of this, SpacePath.core library offers dedicated methods to handle with this situation. Special cases represented by (i) the usage of Wikipathways, and (ii) the mapping expansion, are both shown, with code snippets, in section 3 Supplementary information: library usage.