FSLには Johns Hopkins University の白質アトラスがついてきます。
そのアトラスの領域名を抽出したいと思いました。
Short answer
cat JHU-labels.xml |\
sed -e 's@<label.*">@@' \
-e 's@</label>@@' \
-e 's@ @_@g' -e 's@__@@' |\
sed -n 17,66p
で、以下のようになります。
Middle_cerebellar_peduncle Pontine_crossing_tract_(a_part_of_MCP) Genu_of_corpus_callosum Body_of_corpus_callosum Splenium_of_corpus_callosum ...
もし、アトラスの番号を振りたかったら以下のようにします。
cat JHU-labels.xml |\
sed -e 's@<label.*">@@' \
-e 's@</label>@@' \
-e 's@ @_@g' \
-e 's@__@@' |\
sed -n 17,66p |\
nl -n rz |
sed -E 's@0{4}@@'
この結果は以下になります。
01 Middle_cerebellar_peduncle 02 Pontine_crossing_tract_(a_part_of_MCP) 03 Genu_of_corpus_callosum 04 Body_of_corpus_callosum 05 Splenium_of_corpus_callosum ...
Long answer
領域名は、$FSLDIR/data/atlases/JHU-labels.xml の中に記載されています。
いろいろ作業する際にパスを指定するのはめんどくさいので、これをカレントディレクトリにコピーすることにします。
cp $FSLDIR/data/atlases/JHU-labels.xml .
一度、JHU-labels.xml を見てみます。headコマンドで最初の20行を見てみましょう。
head -n 20 JHU-labels.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<atlas version="1.0">
<header>
<name>JHU ICBM-DTI-81 White-Matter Labels</name>
<type>Label</type>
<images>
<imagefile>/JHU/JHU-ICBM-labels-1mm</imagefile>
<summaryimagefile>/JHU/JHU-ICBM-labels-1mm</summaryimagefile>
</images>
<images>
<imagefile>/JHU/JHU-ICBM-labels-2mm</imagefile>
<summaryimagefile>/JHU/JHU-ICBM-labels-2mm</summaryimagefile>
</images>
</header>
<data>
<label index="0" x="0" y="0" z="0">Unclassified</label>
<label index="1" x="69" y="83" z="36">Middle cerebellar peduncle</label>
<label index="2" x="89" y="97" z="40">Pontine crossing tract (a part of MCP)</label>
<label index="3" x="93" y="152" z="77">Genu of corpus callosum</label>
<label index="4" x="95" y="100" z="97">Body of corpus callosum</label>
領域は <label index からはじまる行に入っているようです。
そこで、次の戦略を立てます。
- <label からはじまって、 “> で終わるところをなくす
- をなくす
- 空白はアンダーラインで置換する
sed は ‘s「区切り文字」「検索語」「区切り文字」「置換語」「区切り文字」’ で検索語を置換語に置き換えることができます。
普通、区切り文字は スラッシュ / が使われますが、他の記号でも大丈夫です。特に、検索語の中にスラッシュが入っている場合は、他の記号を使うと混乱しづらくなります。
今、2つ目で というスラッシュが入っているものがありますので、今、区切り文字は @ を使うことにします。
- <label からはじまって、 “> で終わるところをなくす
は、sed だと以下で表示できます。
sed -e 's@<label.*">@@'
- をなくす
は、以下になります。
sed -e 's@</label>@@'
- 空白はアンダーラインで置換する
は、以下になります。
sed -e 's@ @_@g'
ここで、g は、globalの略と私は覚えています。もし、これがないと、該当する行の最初の空白だけアンダースコアに置き換えられるだけであとの空白は残ります。 g があることにより、その行のすべての空白がアンダースコアに置換されます。
これらをまとめてみます。最初に cat JHU-labels.xml をして、パイプで sed につなげます。sed の後に JHU-labels.xml を指定してもいいのですが、個人的に、パイプでつなげることができるので、catで表示させる方が私は好きです。
cat JHU-labels.xml | sed -e 's@<label.*">@@' -e 's@</label>@@' -e 's@ @_@g'
この結果、以下のようになりました。
<?xml_version="1.0"_encoding="ISO-8859-1"?> <atlas_version="1.0"> __<header> ____<name>JHU_ICBM-DTI-81_White-Matter_Labels</name> ____<type>Label</type> ____<images> ______<imagefile>/JHU/JHU-ICBM-labels-1mm</imagefile> ______<summaryimagefile>/JHU/JHU-ICBM-labels-1mm</summaryimagefile> ____</images> ____<images> ______<imagefile>/JHU/JHU-ICBM-labels-2mm</imagefile> ______<summaryimagefile>/JHU/JHU-ICBM-labels-2mm</summaryimagefile> ____</images> __</header> __<data> Unclassified Middle_cerebellar_peduncle Pontine_crossing_tract_(a_part_of_MCP) Genu_of_corpus_callosum Body_of_corpus_callosum Splenium_of_corpus_callosum (中略) Inferior_fronto-occipital_fasciculus_L Uncinate_fasciculus_R Uncinate_fasciculus_L Tapetum_R Tapetum_L __</data> </atlas>
いい感じです。
あとは、Middle_cerebellar_peduncle から Tapetum_L が何行目かを知れればその行だけ表示すればいいことになります。
行数を知るのは nl コマンドが便利です。先程のコマンドをパイプで nl に通します。
cat JHU-labels.xml | sed -e 's@<label.*">@@' -e 's@</label>@@' -e 's@ @_@g' | nl
1 <?xml_version="1.0"_encoding="ISO-8859-1"?>
2 <atlas_version="1.0">
3 __<header>
4 ____<name>JHU_ICBM-DTI-81_White-Matter_Labels</name>
5 ____<type>Label</type>
6 ____<images>
7 ______<imagefile>/JHU/JHU-ICBM-labels-1mm</imagefile>
8 ______<summaryimagefile>/JHU/JHU-ICBM-labels-1mm</summaryimagefile>
9 ____</images>
10 ____<images>
11 ______<imagefile>/JHU/JHU-ICBM-labels-2mm</imagefile>
12 ______<summaryimagefile>/JHU/JHU-ICBM-labels-2mm</summaryimagefile>
13 ____</images>
14 __</header>
15 __<data>
16 Unclassified
17 Middle_cerebellar_peduncle
18 Pontine_crossing_tract_(a_part_of_MCP)
19 Genu_of_corpus_callosum
20 Body_of_corpus_callosum
(中略)
62 Inferior_fronto-occipital_fasciculus_L
63 Uncinate_fasciculus_R
64 Uncinate_fasciculus_L
65 Tapetum_R
66 Tapetum_L
67 __</data>
68 </atlas>
この中の 17行目から66行目を取り出せばよさそうです。
sed で特定の行だけ表示したい場合は、 sed -n 開始行,終了行p とします。
先程の結果にパイプでつなげてみましょう。
cat JHU-labels.xml | sed -e 's@<label.*">@@' -e 's@</label>@@' -e 's@ @_@g' | sed -n 17,66p
その結果は以下になります。
Middle_cerebellar_peduncle Pontine_crossing_tract_(a_part_of_MCP) (中略) Inferior_cerebellar_peduncle_R__ Inferior_cerebellar_peduncle_L (中略) Tapetum_R Tapetum_L
とてもいい感じです。しかし、JHU-labels.xml のバグといいますか、Inferior cerebellar peduncle の後に空白が2個あったのがアンダースコア2つになっています。これは気持ち悪いので削除しましょう。
これは、 sed -e ‘s@__@@’ でできます。先程のコマンドにちょっとだけ追加します。
cat JHU-labels.xml | sed -e 's@<label.*">@@' -e 's@</label>@@' -e 's@ @_@g' -e 's@__@@' | sed -n 17,66p
この結果、とてもきれいになりました。役に立つと思うのでテキストファイルにしておきます。
ここまではいいのですが、欲が出ます。アトラスの領域番号との対応をさせたいと思いました。これも nl を使えば簡単にできます。nl は -n rz で数字を右揃えでゼロパディングできます。
cat JHU-labels.xml | sed -e 's@<label.*">@@' -e 's@</label>@@' -e 's@ @_@g' -e 's@__@@' | sed -n 17,66p | nl -n rz
000001 Middle_cerebellar_peduncle 000002 Pontine_crossing_tract_(a_part_of_MCP) 000003 Genu_of_corpus_callosum
いいのですが、多くても50領域なので、最初の04つは除きたいと思います。これは、 sed ‘s@0000@@’ でできます。0を4つ繰り返すということで、正規表現を使ってエレガントに表示する場合は sed -E ‘s@0{4}@@’ となります。
cat JHU-labels.xml | sed -e 's@<label.*">@@' -e 's@</label>@@' -e 's@ @_@g' -e 's@__@@' | sed -n 17,66p | nl -n rz | sed -E 's@0{4}@@'
この結果は以下になります。これも使い勝手がいいのでテキストファイルを添付します。
これによって、JHUアトラスの情報を取り出せました。これはいろいろなものに応用できるかと思います。
JHUの大石と申します。JHUアトラスをご紹介いただきありがとうございます。私どもの研究室では、OpenMAP suiteという深層学習による画像パーセレーションモデルを公開しており、現在OpenMAP-T1(T1強調画像をJHU-MNIアトラスに基づく280領域に区分)、OpenMAP-Di(乳児diffusion MRIを168領域に区分)、T2強調画像用のOpenMAP-T2を公開しております。近々、diffusion MRI用のOpenMAP-D、FLAIR画像のWMHをラベルできるOpenMAP-FLを公開予定です。研究のお役に立てることを願っております。https://github.com/OishiLab
大石先生
どうもありがとうございます。JHUアトラスはいつもありがたく使用させていただいております。また、OpenMAP-T1などのアトラスもご紹介いただきありがとうございます。確認させていただきます。今後ともよろしくお願いいたします。