Aurora blog

バイオインフォ・バイオテクノロジーにまつわる情報

空間オミクス解析③:Scanpy/Squidpyを使ってPythonで空間オミクスデータを扱う

Squidpyとは

Squidpyは、シングルセルオミクスデータの探索的データ解析(EDA)に使われるScanpyを開発したFabian Theisのグループがつい最近公開した空間オミクス解析のためのPythonモジュール。

squidpy.readthedocs.io

www.biorxiv.org

以前のエントリで空間オミクスデータのEDAに使えるツールを紹介したが、そのほとんどがRで実装されたものであり、Pythonで実装された目ぼしいツールは見つからなかった。空間オミクスデータを使って病理画像から遺伝子発現を予測する手法*1や、Visiumの空間オミクスデータの解像度を病理画像を使って向上させる手法*2など、機械学習をうまく利用した研究が現れていることからも、Pythonでの開発の基盤が欲しいと感じていたが、今回それがようやく現れたと言える。

auroratummy.hatenablog.com

データの取り扱い

SquidpyはScanpyと同様にAnnDataクラスでデータを扱う。anndataはRのSeuratクラスやSingleCellDataクラスと同じようにシングルセル データのために設計されたデータ型である。遺伝子発現行列の他に、サンプル (細胞/スポット) のメタデータ、計測した遺伝子のメタデータ、次元圧縮後の座標情報やkNNグラフなどの解析結果を一つのオブジェクトで取り扱うことができる。

空間オミクスデータのシングルセルデータとの大きな違いはHE画像などの病理画像情報が付随している場合があることだが、これはAnnDataのadata.uns['spatial']['{library_id}']adata.obsm['spatial']に格納される。VisiumデータをSpace Rangerで解析した場合は、遺伝子発現情報が格納されたhdf5ファイル *3 と画像データや各スポットの座標情報が格納されたspatialフォルダがあれば、Scanpyのread_visiumで画像もまとめて読み込むことができる。

!tree 
├── data
│   ├── filtered_feature_bc_matrix.h5
│   └── spatial
│       ├── aligned_fiducials.jpg
│       ├── detected_tissue_image.jpg
│       ├── scalefactors_json.json
│       ├── tissue_hires_image.png
│       ├── tissue_lowres_image.png
│       └── tissue_positions_list.csv
└── squidpy.ipynb
import scanpy as sc
adata = sc.read_visium("./data/", count_file="filtered_feature_bc_matrix.h5")
adata
AnnData object with n_obs × n_vars = 4992 × 36601
    obs: 'in_tissue', 'array_row', 'array_col'
    var: 'gene_ids', 'feature_types', 'genome'
    uns: 'spatial'
    obsm: 'spatial'

adata.uns['spatial']['{library_id}']spatialフォルダに含まれる画像や各スポットの座標情報が辞書型で格納される。

adata.uns["spatial"]["Parent_Visium_Human_Cerebellum"].keys()
dict_keys(['images', 'scalefactors', 'metadata'])

`adata.uns['spatial']['{library_id}']["images"]には2つの解像度 (hi & low resolution) の画像データがarray型で格納される。

# adata.uns["spatial"]["Parent_Visium_Human_Cerebellum"]["images"]["hires"]
adata.uns["spatial"]["Parent_Visium_Human_Cerebellum"]["images"]["lowres"][:2, :2, :] # (x, y, RGB)
array([[[0.7019608, 0.7176471, 0.7176471],
        [0.7019608, 0.7137255, 0.7176471]],

       [[0.7019608, 0.7137255, 0.7176471],
        [0.7019608, 0.7137255, 0.7176471]]], dtype=float32)

adata.obsm['spatial']には各スポットの座標情報が格納されている。

adata.obsm['spatial'][:5, :] # (x, y)
array([[3366, 1800],
       [9312, 7772],
       [5227, 2153],
       [3598, 8871],
       [8745, 3459]])

adata.obsm['spatial']は圧縮前の画像データ ((フォルダspatialの画像データは高解像度(hires)のものも元の画像からは圧縮されている)) 上の座標 (ピクセル) データであるため、hires & lowresいずれの画像上に直接投影することができない。adata.uns['spatial']['{library_id}']["scalefactors"]には画像上にスポットを投影するための情報が格納されている。

tissue_hires_scaleftissue_lowres_scalefにはhires/lowres両画像が元の画像からどの程度縮小されたものであるか(=縮尺)が格納される。spot_diameter_fullresは元画像におけるスポットのサイズ (ピクセル数) を表す。これらの情報をもとにスポットの場所をhires/lowres画像上へ投影することができる。

adata.uns["spatial"]["Parent_Visium_Human_Cerebellum"]["scalefactors"]
{'spot_diameter_fullres': 89.55377,
 'tissue_hires_scalef': 0.150015,
 'fiducial_diameter_fullres': 144.66379000000003,
 'tissue_lowres_scalef': 0.045004502}

Scanpy/SquidpyはImaging mass cytometryやFISHベースの手法で得られた空間発現情報も扱うことができる、という触れ込みであるが、sc.read_visium的な関数はVisium以外のデータにはまだ用意されておらず、現状は手作業でadata.uns["spatial"]adata.obsm["spatial"]を用意する必要がありそうだ。*4

出来ること

ImageContainer

SquidpyではImageContainerクラスという画像情報を扱うクラスを新たに提供している。ImageContainerは画像をxarray *5 やDaskで扱いやすい&メモリ効率的な形で保存する。SquidpyはImageContainerを入力とした様々な画像解析の機能を提供している。*6

ImageContainerの作り方はとても簡単。

image = adata.uns["spatial"]["Parent_Visium_Human_Cerebellum"]["images"]["hires"]
img = sq.im.ImageContainer(image)
img
ImageContainer object with 1 layer:
    image: y (2000), x (2000), channels (3)

空間情報を利用した解析

anndataクラスでデータを扱うため、Scanpyが提供するシングルセル解析用の機能 (e.g. Embedding, Graph-based clustering, DEG analysis) はすべてそのまま適用することができる。Squidpyではこれに加えて空間オミクスデータならではの以下の解析手法を提供している。

  • 近い場所に位置している細胞種の抽出 Link
  • 特定の領域で発現している遺伝子の抽出:自己相関の指標 Moran's Iを利用 Link
  • リガンドーレセプター解析 (CellphoneDBの情報を利用): 特定のリガンド・レセプターのペアを高発現する空間を探索

外部ツールとの連携

Napariという画像用のビューアーと連携している。AnnDataとImageContentを指定して以下のコマンドを実施するとGUIが立ち上がりインタラクティブに遺伝子発現の可視化を行うことができる。Napariは可視化だけでなく、病理学で行われるようなマニュアルで画像にアノテーションをつける事もできる。マニュアルアノテーションの内容はadata.obsへ保存されるため、プログラムでの解析へシームレスにつなげることができる。Napariで作業すると自分のPC ((メモリ16GB, 2.3GHz Quad core Intel Core i7Mac Book Pro)) の動作がだいぶ遅くなったので、ある程度のメモリは必要と思われる。

%gui qt
viewer = img.interactive(adata)

f:id:auroratummy:20210227013112p:plain

そのほかにもTensorflow/Pytorchといった深層学習用のライブラリとの連携や、Tanglamやstlearnといった空間オミクスとシングルセルデータの統合解析手法もScanpy/Squidpyからそのまま使えるようにしていたり、Rで実装されているEDA用のツールと比較してもかなりよく出来ている印象。*7

*1:https://www.nature.com/articles/s41551-020-0578-x

*2:https://www.biorxiv.org/content/10.1101/2020.02.28.963413v2.full

*3:filtered_feature_bc_matrix.h5 or raw_feature_bc_matrix.h5

*4:一般的なフォーマットが存在しない現状は関数も開発できないのであろう

*5:Pandasよりも多次元配列を扱いやすいらしい

*6:最初からadata.unsの画像データをImageContainer型にしないのは何故だろうか

*7:機械学習を使った研究への展開が容易になりそうで、とてもありがたい