ある研究データセットにおいて、被験者リストに性別や年齢の記載もれがあり、MRIのDICOMデータから取得することを考えてみました。
説明が不要な方は、dcmtkさえインストールしてあれば、次のワンライナーで得られます。
$ for f in $(ls -F | grep /); do echo $f; dcmdump $(find $f -type f | sed -n 1p) | grep -E "0010,0020|0010,0030|0010,0040|0010,1010" | awk '{ print $7, $3}' ; echo ""; done
以下、解説です。
- DICOMタグ
- DICOMヘッダを参照できるプログラム
DICOMでは、被験者情報は以下のタグで規定されています。
(0010,0020) 被験者ID
(0010,0030) 被験者生年月日
(0010,0040) 被験者性別
(0010,1010) 被験者年齢
なので、この情報を抽出できればいいわけです。
LinuxではDICOMのヘッダを確認するツールとしては、dcmtk がよく使われているかと思います。
Ubuntuでは、コマンド一発で入ります。
$ sudo apt install dcmtk
dcmdumpというのがヘッダを出力するプログラムとなります。
DICOMは何千ものファイルがひとつのディレクトリに入っています。しかし、被験者情報はすべて同一ですから、
とりあえずひとつのファイルを参照できればいいことになります。
(なお、今回は、ひとつのディレクトリに複数の被験者が入っている場合は想定していません。ひとつのディレクトリに一人のデータが入っていることを想定しています。モダリティ毎にサブディレクトリがあるのは問題ありません)
たいていの場合、DICOMファイルは .dcm という拡張子がつきますが、ときにはつかない場合もあります。
ただ、ラッキーなことに、DICOMファイル以外にファイルが入る可能性は少ないですから、とりあえずファイルをひとつ選択します。
これは、 find と sed を使えば可能になります。
find 検索ディレクトリ -type f
で検索ディレクトリ以下にあるファイルを検索できますし、
sed -n 1p
をパイプでつないであげれば、findの結果のうち、1番上にあるものだけを表示できるわけです。
これまで説明したことを組み合わせると
dcmdump $(find 検索ディレクトリ -type f | sed -n 1p)
となります。
grep を使います。grep はオプション -E を使えば、検索キーワードを | で区切ることで複数のキーワード検索ができます。
今の場合は、
grep -E "0010,0020|0010,0030|0010,0040|0010,1010"
となります。
先程のものと組み合わせると、
dcmdump $(find 検索ディレクトリ -type f | sed -n 1p) | grep -E "0010,0020|0010,0030|0010,0040|0010,1010"
となるわけです。
今、検索ディレクトリを . に置き換えて実行してみると以下のようになりました。
(0010,0020) LO [Subject001] # 28, 1 PatientID
(0010,0030) DA [19730903] # 8, 1 PatientBirthDate
(0010,0040) CS [F] # 2, 1 PatientSex
(0010,1010) AS [042Y] # 4, 1 PatientAge
いい感じで抜き出せています。
こうなると少し贅沢をしたくなってきます。
awkを使って、出力形式を変更してみます。
[Subject001] は第3列、PatientIDは第7列にありますので、以下のようにしてみます。
dcmdump $(find -type f | sed -n 1p) | grep -E "0010,0020|0010,0030|0010,0040|0010,1010" | awk '{ print $7, $3 }'
PatientID [Subject001]
PatientBirthDate [19730903]
PatientSex [F]
PatientAge [042Y]
いい感じですね。
最後は、forループに入れ、一気に情報を取得できるようにします。
for f in $(ls -F | grep /); do echo $f; dcmdump $(find $f -type f | sed -n 1p) | grep -E "0010,0020|0010,0030|0010,0040|0010,1010" | awk '{ print $7, $3}' ; echo ""; done
これで一気に情報を取得できるようになりました。