【初心者向け】基礎&実践プログラミング

初心者がつまづきやすいところ、最短で実力が身につく方法をお伝えします。

PythonによるDiffusion MRIのbvec fileの極性変更

はじめに

diffusion MRIで重要なMPGのGradient Tableであるbvecの極性がMRI装置と解析ソフトウェアで互換性がない。 被験者は200人以上いるため、一人ひとり手直しするのは困難である。 そこで、Pythonでbvec fileの中の極性を任意に変更できるスクリプトを作成した。 FSLやMRtrixではbvecの極性を修正するコマンドはないんじゃないかな?

コードの中身

パッケージのインポート

import pandas as pd
import numpy as np
from argparse import ArgumentParser

コマンドライン引数の設定

argparseを使うとこのPythonプログラムに必要な種々の引数を設定することがきる。 今回の場合だと、 -i : inputするbvec file -o : outputするbvec file -x : x軸の1(極性を反転しない) or -1(極性を反転,default) -y : y軸の1(極性を反転しない) or -1(極性を反転,default) -z : z軸の1(極性を反転しない) or -1(極性を反転,default)

def get_option():
    argparser = ArgumentParser(usage='reorient_bvec.py -i <Input bvec file> -o <Output bvec file> [options]')
    argparser.add_argument('-i', type=str, help='Specify <Input bvec file>')
    argparser.add_argument('-o', type=str, help='Specify <Output bvec file>')
    argparser.add_argument('-x',  type=int, default=1,help='Specify whether x axis is <1 or -1>')
    argparser.add_argument('-y',  type=int, default=1,help='Specify whether y axis is <1 or -1>')
    argparser.add_argument('-z',  type=int, default=1,help='Specify whether z axis is <1 or -1>')
    return argparser.parse_args()

極性の変更

  1. "open()"でbvec fileを開く
  2. "readlines()"ですべてを読み出し一行づつ処理と約束
  3. "close()"でbvec fileを閉じる
  4. for文を使って一行ずつ読み出して値の間の空白をカンマ(,)に置換
  5. values変数に一行づつ追加。ただしこのとき、values変数の中身(dtype)はfloatに指定
  6. valuesをデータフレームに変換
  7. 受け取ったx_pol, y_pol, z_polに従ってx,y,zの極性を変更
  8. "to_csv()"でテキストとして保存。ただしタブ区切り(seq='\t')でheaderとindexはFalseにしてつけない。
def reorient(input,output,x_pol,y_pol,z_pol):
    f = open(input)
    line = f.readlines()
    f.close()
    values =[]
    for raw in line:
        values.append(raw.split())
    values = np.array(values, dtype=float)
    df = pd.DataFrame({'x':values[0,:],'y':values[1,:],'z':values[2,:]})

    # change x to -x
    df['x'] = df['x'] * x_pol
    df['x'][0] = 0
    # change y to -y
    df['y'] = df['y'] * y_pol
    df['y'][0] = 0
    # change z to -z
    df['z'] = df['z'] * z_pol
    df['z'][0] = 0
    df.T.to_csv(output,header=False,index=False,sep ='\t')

実行

最後に以下を実行。

args = get_option()
reorient(args.i,args.o,args.x,args.y,args.z)

使ってみた

help画面

$reorient_bvec.py -h
usage: reorient_bvec.py -i <Input bvec file> -o <Output bvec file> [options]

optional arguments:
  -h, --help  show this help message and exit
  -i I        Specify <Input bvec file>
  -o O        Specify <Output bvec file>
  -x X        Specify whether x axis is <1 or -1>
  -y Y        Specify whether y axis is <1 or -1>
  -z Z        Specify whether z axis is <1 or -1>

bvec fileの中身

1行目から順にx,y,zに対応したMPGのベクトルファイルです。

0 -0.217930346727371 0.183526918292046 0.383256644010544 -0.410334378480911 -0.202136784791946 -0.852467894554138 -0.736984968185425 -0.424142956733704 -0.743488430976868 -0.642241656780243 -0.314430356025696 -0.303920179605484 -0.635029315948486 -0.975241184234619 -0.842172503471375 0.02119112201035 0.017083311453462 0.669762194156647 0.350858598947525 -0.176277682185173 0.225432544946671 0.662433862686157 0.334164470434189 0.20159624516964 0.396999925374985 0.717438399791718 0.722378551959991 0.856116056442261 0.868275225162506 0.982918977737427 0 -0.217930346727371 0.183526918292046 0.383256644010544 -0.410334378480911 -0.202136784791946 -0.852467894554138 -0.736984968185425 -0.424142956733704 -0.743488430976868 -0.642241656780243 -0.314430356025696 -0.303920179605484 -0.635029315948486 -0.975241184234619 -0.842172503471375 0.02119112201035 0.017083311453462 0.669762194156647 0.350858598947525 -0.176277682185173 0.225432544946671 0.662433862686157 0.334164470434189 0.20159624516964 0.396999925374985 0.717438399791718 0.722378551959991 0.856116056442261 0.868275225162506 0.982918977737427
0 -0.412680119276047 -0.409769654273987 -0.058996170759201 -0.659401714801788 -0.901793777942657 -0.511457681655884 -0.465032130479813 -0.066757045686245 -0.098933920264244 -0.75407212972641 -0.949280381202698 -0.609742164611816 -0.585166573524475 -0.193069934844971 -0.237830027937889 -0.804597735404968 -0.9742192029953 -0.571449518203735 -0.603594779968262 -0.288592159748077 -0.28386327624321 -0.741296827793121 -0.942338287830353 -0.896425783634186 -0.651651620864868 -0.084958553314209 -0.45000359416008 -0.494898587465286 -0.220817357301712 -0.173311769962311 0 -0.412680119276047 -0.409769654273987 -0.058996170759201 -0.659401714801788 -0.901793777942657 -0.511457681655884 -0.465032130479813 -0.066757045686245 -0.098933920264244 -0.75407212972641 -0.949280381202698 -0.609742164611816 -0.585166573524475 -0.193069934844971 -0.237830027937889 -0.804597735404968 -0.9742192029953 -0.571449518203735 -0.603594779968262 -0.288592159748077 -0.28386327624321 -0.741296827793121 -0.942338287830353 -0.896425783634186 -0.651651620864868 -0.084958553314209 -0.45000359416008 -0.494898587465286 -0.220817357301712 -0.173311769962311
0 -0.884421586990356 -0.89353609085083 -0.921755850315094 -0.629932701587677 -0.381979912519455 -0.108210533857346 -0.490508288145065 -0.903131365776062 -0.661390364170074 0.137480318546295 0.000462443917058 0.73201584815979 0.504299402236938 0.107836477458477 0.483923941850662 0.59344208240509 0.224955901503563 0.474198371171951 0.715941071510315 0.941084921360016 0.931988179683685 0.107983581721783 -0.01824214681983 -0.394689381122589 -0.646329164505005 -0.691421866416931 -0.525039196014404 -0.148797869682312 0.444227457046509 0.061913453042507 0 -0.884421586990356 -0.89353609085083 -0.921755850315094 -0.629932701587677 -0.381979912519455 -0.108210533857346 -0.490508288145065 -0.903131365776062 -0.661390364170074 0.137480318546295 0.000462443917058 0.73201584815979 0.504299402236938 0.107836477458477 0.483923941850662 0.59344208240509 0.224955901503563 0.474198371171951 0.715941071510315 0.941084921360016 0.931988179683685 0.107983581721783 -0.01824214681983 -0.394689381122589 -0.646329164505005 -0.691421866416931 -0.525039196014404 -0.148797869682312 0.444227457046509 0.061913453042507

y軸の極性変更

このケースだとy軸の極性のみを変更すればよかったので、bval file(bvals.bval)のy軸だけ極性を変更する。 input(-i) : bvals.bval output(-o) : reorient_bvals.bval y軸(-y) : -1を記載し極性変更

$python3 reorient_bval.py -i bvals.bval -o reorient_bvals.bval -y -1

実行した結果がこちら。2行目のy軸のみの極性が変更されている。 あとは、このスクリプトを被験者分、for文で回すだけ。

0 -0.217930346727371 0.183526918292046 0.383256644010544 -0.410334378480911 -0.202136784791946 -0.852467894554138 -0.736984968185425 -0.424142956733704 -0.743488430976868 -0.642241656780243 -0.314430356025696 -0.303920179605484 -0.635029315948486 -0.975241184234619 -0.842172503471375 0.02119112201035 0.017083311453462 0.669762194156647 0.350858598947525 -0.176277682185173 0.225432544946671 0.662433862686157 0.334164470434189 0.20159624516964 0.396999925374985 0.717438399791718 0.722378551959991 0.856116056442261 0.868275225162506 0.982918977737427 0 -0.217930346727371 0.183526918292046 0.383256644010544 -0.410334378480911 -0.202136784791946 -0.852467894554138 -0.736984968185425 -0.424142956733704 -0.743488430976868 -0.642241656780243 -0.314430356025696 -0.303920179605484 -0.635029315948486 -0.975241184234619 -0.842172503471375 0.02119112201035 0.017083311453462 0.669762194156647 0.350858598947525 -0.176277682185173 0.225432544946671 0.662433862686157 0.334164470434189 0.20159624516964 0.396999925374985 0.717438399791718 0.722378551959991 0.856116056442261 0.868275225162506 0.982918977737427
0 0.412680119276047 0.409769654273987 0.058996170759201 0.659401714801788 0.901793777942657 0.511457681655884 0.465032130479813 0.066757045686245 0.098933920264244 0.75407212972641 0.949280381202698 0.609742164611816 0.585166573524475 0.193069934844971 0.237830027937889 0.804597735404968 0.9742192029953 0.571449518203735 0.603594779968262 0.288592159748077 0.28386327624321 0.741296827793121 0.942338287830353 0.896425783634186 0.651651620864868 0.084958553314209 0.45000359416008 0.494898587465286 0.220817357301712 0.173311769962311 0 0.412680119276047 0.409769654273987 0.058996170759201 0.659401714801788 0.901793777942657 0.511457681655884 0.465032130479813 0.066757045686245 0.098933920264244 0.75407212972641 0.949280381202698 0.609742164611816 0.585166573524475 0.193069934844971 0.237830027937889 0.804597735404968 0.9742192029953 0.571449518203735 0.603594779968262 0.288592159748077 0.28386327624321 0.741296827793121 0.942338287830353 0.896425783634186 0.651651620864868 0.084958553314209 0.45000359416008 0.494898587465286 0.220817357301712 0.173311769962311
0 -0.884421586990356 -0.89353609085083 -0.921755850315094 -0.629932701587677 -0.381979912519455 -0.108210533857346 -0.490508288145065 -0.903131365776062 -0.661390364170074 0.137480318546295 0.000462443917058 0.73201584815979 0.504299402236938 0.107836477458477 0.483923941850662 0.59344208240509 0.224955901503563 0.474198371171951 0.715941071510315 0.941084921360016 0.931988179683685 0.107983581721783 -0.01824214681983 -0.394689381122589 -0.646329164505005 -0.691421866416931 -0.525039196014404 -0.148797869682312 0.444227457046509 0.061913453042507 0 -0.884421586990356 -0.89353609085083 -0.921755850315094 -0.629932701587677 -0.381979912519455 -0.108210533857346 -0.490508288145065 -0.903131365776062 -0.661390364170074 0.137480318546295 0.000462443917058 0.73201584815979 0.504299402236938 0.107836477458477 0.483923941850662 0.59344208240509 0.224955901503563 0.474198371171951 0.715941071510315 0.941084921360016 0.931988179683685 0.107983581721783 -0.01824214681983 -0.394689381122589 -0.646329164505005 -0.691421866416931 -0.525039196014404 -0.148797869682312 0.444227457046509 0.061913453042507

注意

FSLのコマンドのひとつであるfslreorient2stdを使用した際には注意してください。 画像がFSL座標系でなかったとしてFSL座標系にreorientされたら、reorient後の画像(DWI)とbvecの対応はなくなります。 この場合は、bvecも同様にしてreorientしてやらなければいけません。 このような場合でも今回で作成したコードでbvecを修正できちゃいますね。

まとめ

diffusion MRIで出力されるGradient Tableであるbvecの極性を一括変更するためのスクリプトを作成した。 ここでは、 - argparseの扱い - list, array, DataFrameの行き来 - DataFrameでの一部の値の変更の仕方 を取得できればいいと思う。

使用したコード

import glob
import pandas as pd
import numpy as np
from argparse import ArgumentParser

def get_option():
    argparser = ArgumentParser(usage='reorient_bvec.py -i <Input bvec file> -o <Output bvec file> [options]')
    argparser.add_argument('-i', type=str, help='Specify <Input bvec file>')
    argparser.add_argument('-o', type=str, help='Specify <Output bvec file>')
    argparser.add_argument('-x',  type=int, default=1,help='Specify whether x axis is <1 or -1>')
    argparser.add_argument('-y',  type=int, default=1,help='Specify whether y axis is <1 or -1>')
    argparser.add_argument('-z',  type=int, default=1,help='Specify whether z axis is <1 or -1>')
    return argparser.parse_args()

def reorient(input,output,x_pol,y_pol,z_pol):
    f = open(input)
    line = f.readlines()
    f.close()
    values =[]
    for raw in line:
        values.append(raw.split())
    values = np.array(values, dtype=float)
    df = pd.DataFrame({'x':values[0,:],'y':values[1,:],'z':values[2,:]})

    # change x to -x
    df['x'] = df['x'] * x_pol
    df['x'][0] = 0
    # change y to -y
    df['y'] = df['y'] * y_pol
    df['y'][0] = 0
    # change z to -z
    df['z'] = df['z'] * z_pol
    df['z'][0] = 0
    df.T.to_csv(output,header=False,index=False,sep ='\t')

args = get_option()
reorient(args.i,args.o,args.x,args.y,args.z)



頑張れ!喝!!の代わりにB!ブックマークを押していただけるとただただうれしいです(^^)! ↓