Skip to content
Snippets Groups Projects
get_b0s.py 3.41 KiB
#!/usr/bin/env python
#
# get_b0s.py - Utility to get the b0s out of a dMRI file
#
# Author: Fidel Alfaro Almagro <fidel.alfaroalmagro@ndcn.ox.ac.uk>
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
# Author: Michiel Cottaar <michiel.cottaar@ndcn.ox.ac.uk>
#
# pylint: disable=C0103,E0602,C0114,C0115,C0116,R0913,R0914,R0915
#

import os.path as op
import sys
import argparse
import os.path
from fsl import wrappers

class MyParser(argparse.ArgumentParser):
    def error(self, message):
        sys.stderr.write(f'error: {message}\n')
        self.print_help()
        sys.exit(2)

class Usage(Exception):
    def __init__(self, msg):
        self.msg = msg

def get_b0s(inputFile, bvalFilename, outputFile, outputIndFile, desiredNumber,
            B0limit=100):
    with open(bvalFilename, 'r', encoding="utf-8") as f:
        line = f.readlines()

    line = line[0].split()
    indices = [i for i, x in enumerate(line) if int(x) < B0limit]

    with open(outputIndFile , 'wt', encoding="utf-8") as f:
        f.write(" ".join([str(x) for x in indices]))

    indices = indices[0:desiredNumber]

    wrappers.fslselectvols(src=inputFile, out=outputFile, vols=indices)


def main():
    parser = MyParser(description='UKB tool to get a B0 of a set of B0 images')
    parser.add_argument('-i', dest="inputFile", type=str, nargs=1,
                        help='Input File')
    parser.add_argument('-o', dest="outputFile", type=str, nargs=1,
                        help='Output File')
    parser.add_argument('-n', dest='desiredNumber', type=int, nargs=1,
                        help='Desired number of B0s from file. ' +
                             'If none specified, all will be selected')
    parser.add_argument('-l', dest='B0limit', type=int, default=[100], nargs=1,
                        help='Limit B0 value. (Default 100)')
    parser.add_argument('-a', dest='bvalFilename', type=str, default='',
                        nargs=1,
                        help='bval file. (Default: Same basename ' +
                             'as the input file)')

    argsa = parser.parse_args()

    if argsa.inputFile is None:
        parser.print_help()
        sys.exit()

    if argsa.outputFile is None:
        parser.print_help()
        sys.exit()

    inputFile  = argsa.inputFile[0]
    outputFile = argsa.outputFile[0]

    baseDir = os.path.dirname(inputFile)
    outDir  = os.path.dirname(outputFile)
    baseN   = os.path.basename(inputFile).split('.')[0]
    outN    = os.path.basename(outputFile).split('.')[0]

    if argsa.bvalFilename == '':
        bvalFilename = op.join(baseDir, baseN+".bval")
    else:
        bvalFilename = argsa.bvalFilename[0]

    with open(bvalFilename, 'r', encoding="utf-8") as f:
        line = f.readlines()

    line = line[0].split()
    B0limit = int(argsa.B0limit[0])
    indices = [i for i, x in enumerate(line) if int(x) < B0limit]

    if argsa.desiredNumber is None:
        desiredNumber = len(indices)
    else:
        desiredNumber = argsa.desiredNumber[0]

    if desiredNumber > len(indices):
        print(f"There are only {len(indices)} B0. It is not possible " +
              f"to have {desiredNumber}")
        sys.exit()

    if desiredNumber <= 0:
        print("The number of B0 must be positive")
        sys.exit()

    outputIndFile = op.join(outDir, outN + '_indices.txt')

    get_b0s(inputFile, bvalFilename, outputFile, outputIndFile,
            desiredNumber, B0limit)

if __name__ == "__main__":
    main()