domains / science / spatial-proteomics-analysis / spatial-proteomics
The two skills cover the same task but with different emphases and conflicting technical guidance. The first copy (OpenClaw) provides a concise, code-heavy workflow using scimap and squidpy, but it recommends log1p transformation, which is generally incorrect for continuous protein intensity data. The second copy (GPTomics) provides a much deeper conceptual framework, explicitly warning against log1p and recommending arcsinh/z-score, and it details platform-specific confounds and segmentation errors. Because the first copy's preprocessing step is technically flawed compared to the second, and the second copy contains substantial material (platform decision logic, governing principles) missing from the first, crowning one would hide the correct approach or the practical code structure. They must be combined to get the correct preprocessing and the complete workflow.
| Repository | Path |
|---|---|
| FreedomIntelligence/OpenClaw-Medical-Skills | skills/spatial-transcriptomics-analysis/bioSkills/spatial-proteomics/SKILL.md |
| GPTomics/bioSkills | spatial-transcriptomics/spatial-proteomics/SKILL.md |
| Role | Repository | Path |
|---|---|---|
| peer | FreedomIntelligence/OpenClaw-Medical-Skills | skills/spatial-transcriptomics-analysis/bioSkills/spatial-proteomics/SKILL.md |
| peer | GPTomics/bioSkills | spatial-transcriptomics/spatial-proteomics/SKILL.md |
# Spatial Proteomics Analysis
## 1. Data Loading & Version Check
Verify installed versions of `scimap`, `scanpy`, `anndata`, and `squidpy`. If versions differ from reference (scimap 2.0+, scanpy 1.10+), introspect APIs before running code.
```python
import scimap as sm
import anndata as ad
import squidpy as sq
# Load data (cell x marker matrix with spatial coordinates)
adata = ad.read_h5ad('spatial_proteomics.h5ad')
# Ensure adata.obsm['spatial'] and adata.X are populated
```
## 2. Preprocessing (Critical)
**Do NOT use log1p.** Protein intensity is continuous, not count-based. Use arcsinh or z-score normalization to handle antibody/batch confounds.
```python
# Recommended: arcsinh transform (cofactor ~15-20 for fluorescence, adjust for mass spec)
# sm.pp.arcsinh(adata, cofactor=15)
# OR z-score per marker
# sm.pp.zscore(adata)
# Rescale markers if necessary
sm.pp.rescale(adata)
# Batch correction if multiple FOVs
sm.pp.combat(adata, batch_key='fov')
```
## 3. Phenotyping
Choose between manual gating (for known markers) or clustering (for discovery).
```python
# Gating approach
phenotype_markers = {
'T_cell': ['CD3', 'CD45'],
'B_cell': ['CD20', 'CD45'],
'Macrophage': ['CD68', 'CD163'],
'Tumor': ['panCK', 'Ki67']
}
sm.tl.phenotype_cells(adata, phenotype=phenotype_markers, gate=0.5, label='phenotype')
# OR Clustering approach
sm.tl.cluster(adata, method='leiden', resolution=1.0)
```
## 4. Spatial Analysis
Build spatial graphs and analyze neighborhoods.
```python
# Build spatial neighbors
sm.tl.spatial_distance(adata, x_coordinate='X', y_coordinate='Y')
# Neighborhood enrichment
sm.tl.spatial_interaction(adata, phenotype='phenotype', method='knn', knn=10)
# Spatial clustering
sm.tl.spatial_cluster(adata, phenotype='phenotype')
```
## 5. Visualization
```python
# Spatial scatter
sm.pl.spatial_scatterPlot(adata, colorBy='phenotype', x='X', y='Y', s=5)
# Interaction heatmap
sm.pl.spatial_interaction(adata)
# Image overlay
sm.pl.image_viewer(adata, markers=['CD3', 'CD20', 'panCK'])
```
## 6. Platform-Specific Considerations
- **CODEX/PhenoCycler**: Watch for cycle-to-cycle registration drift and photobleaching.
- **IMC/MIBI**: Handle metal-channel spillover (compensation). For deep IMC pipeline mechanics, defer to `imaging-mass-cytometry` skills.
- **CyCIF/Opal**: Account for bleach/restain degradation and spectral unmixing artifacts.
## 7. Integration with Transcriptomics
If matched spatial transcriptomics (e.g., Xenium, MERFISH) is available, use `squidpy` to compare spatial patterns across modalities.
```python
sq.gr.spatial_neighbors(adata_protein)
sq.gr.spatial_neighbors(adata_rna)
```
## Key Principles
1. **Intensity is not Count**: Never apply log1p as if data were UMIs.
2. **Segmentation is Critical**: Cell masks are the dominant error source. Use whole-cell segmentation (e.g., Mesmer) to avoid phantom double-positives from lateral spillover.
3. **Panel is Bounded**: Absence of a marker means it wasn't stained, not that the protein is absent.