From 2539397284dca76a62a729aa715b25372a5d023a Mon Sep 17 00:00:00 2001 From: Fidel Alfaro Almagro <falmagro@fmrib.ox.ac.uk> Date: Fri, 10 Mar 2023 12:27:06 +0000 Subject: [PATCH] Adding some config functionality --- bip/data/config/config.toml | 3 + bip/main.py | 60 +------------------ bip/pipelines/dMRI_diff/diff_gdc.py | 6 +- .../dMRI_fieldmap/fieldmap_post_topup.py | 6 +- bip/pipelines/fMRI_rest/rfMRI_prepare.py | 6 +- bip/pipelines/fMRI_task/tfMRI_prepare.py | 6 +- bip/pipelines/struct_T1/T1_gdc.py | 6 +- bip/pipelines/struct_T2_FLAIR/T2_FLAIR_gdc.py | 6 +- bip/pipelines/struct_asl/asl_proc.py | 6 +- bip/pipelines/struct_swMRI/swMRI_gdc.py | 6 +- bip/pipelines/struct_swMRI/swMRI_proc.py | 5 +- bip/utils/__init__.py | 8 ++- bip/utils/get_b0s.py | 29 +++++---- bip/utils/get_dwell_time.py | 11 ++++ bip/utils/log_utils.py | 5 +- bip/utils/read_json_field.py | 24 ++++---- 16 files changed, 91 insertions(+), 102 deletions(-) create mode 100644 bip/data/config/config.toml diff --git a/bip/data/config/config.toml b/bip/data/config/config.toml new file mode 100644 index 0000000..8f76c2d --- /dev/null +++ b/bip/data/config/config.toml @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:40f00756fbdc99c6f632f2e10fe23020bef650c5b8a4abc5afea34efb099e1e4 +size 32 diff --git a/bip/main.py b/bip/main.py index fef7f0e..b6402d4 100755 --- a/bip/main.py +++ b/bip/main.py @@ -49,7 +49,7 @@ class Context: def __init__(self, subject=""): self.subject = subject - self.BB_BIN_DIR = bip.__path__[0] + self.BIPDIR = bip.__path__[0] self.FSLDIR = os.environ['FSLDIR'] self.gdc = self.get_data('GDC/UKB.txt') @@ -77,7 +77,7 @@ class Context: def get_data(self, fileName): fileName.replace('/', os.sep) - basedir = self.BB_BIN_DIR + os.sep + 'data' + os.sep + basedir = self.BIPDIR + os.sep + 'data' + os.sep return basedir + fileName #def save_context(self, file_name): @@ -94,26 +94,7 @@ def parseArguments(ctx): parser.add_argument("subjectFolder", help='Subject Folder', action="store") parser.add_argument("-q", "--queue", help='Queue modifier (default: normal)', action="store", nargs="?", dest="queue", default="normal") - parser.add_argument("-n", "--normcheck", action="store_false", default=True, - help='Do NOT check Normalisation in structural image '+\ - '(default if flag not used: Check normalisation)', - dest="norm_check") - parser.add_argument("-P", "--namingPatterns", action="store", nargs="?", - default=ctx.get_data("config/naming_pattern_UKBB.json"), - help='File with the naming patterns coming from ' +\ - 'dcm2niix (default: UKB naming patterns)', - dest="naming_patterns") - parser.add_argument("-c", "--coeff", action="store", nargs="?", - default=ctx.get_data("GDC/UKB.txt"), - help='Coefficient file for the GDC (Gradient ' +\ - 'Distiortion Correction). \n' + - ' Options: \n' + - ' none--> No GDC is performed' + - ' <path to file> --> Uses the user-pecified '+\ - 'gradients file' + - ' --> If this option is not used, the '+\ - 'default is the UKB', - dest="coeff") + parser.add_argument("-C", "--coils_SWI",action="store",nargs="?",default=32, help='Number of coils for SWI data. Default: 32. 0 ' +\ 'means "no separate coil data"', @@ -183,28 +164,6 @@ def parseArguments(ctx): ctx.subject = subject ctx.argsa = argsa - # Setting up logging - # Parsing coefficient file argument - if not argsa.coeff: - coeff = "skyra" - else: - coeff = argsa.coeff - if coeff == "": - coeff = "skyra" - if coeff not in ["skyra", "prisma", "none"]: - if not op.exists(coeff): - log.error("ERROR: Subject cannot be run. Incorrect GDC file specified: " + - coeff) - sys.exit(1) - - # Deciding Grafient coefficients file - if coeff == "skyra": - coeff = ctx.get_data("GDC/bb_GDC_coeff_skyra.grad") - elif coeff == "prisma": - coeff = ctx.get_data("GDC/bb_GDC_coeff_prisma.grad") - if not op.exists(coeff): - coeff = "none" - # Parsing number of SWI coils argument if not argsa.coils_SWI: coils_SWI = 32 @@ -266,25 +225,12 @@ def parseArguments(ctx): else: queue = argsa.queue.split(",") - # Check normalisation argument - norm_check = argsa.norm_check - # Check complex phase complex_phase = argsa.complex_phase # Check inverted Phase Encoding Direction for dMRI inverted_PED = argsa.inverted_PED - # Parsing naming pattern argument - naming_patterns = argsa.naming_patterns - naming_patterns = naming_patterns.strip() - - if not op.exists(naming_patterns): - log.error("ERROR: Subject cannot be run. Incorrect naming pattern file specified: " + - naming_patterns) - sys.exit(1) - ctx.naming_patterns = naming_patterns - # Parsing B files argument B_files = argsa.B_files B_files = B_files.strip() diff --git a/bip/pipelines/dMRI_diff/diff_gdc.py b/bip/pipelines/dMRI_diff/diff_gdc.py index 0c91479..d009a7b 100755 --- a/bip/pipelines/dMRI_diff/diff_gdc.py +++ b/bip/pipelines/dMRI_diff/diff_gdc.py @@ -27,14 +27,16 @@ def run(ctx, with redirect_logging(job_name(run), outdir=logs_dir): - if ctx.gdc != '': + gdc = ctx.get('gdc', None) + + if gdc not in (None, "", "none"): #Calculate and apply the Gradient Distortion Unwarp # TODO: Review the "half=True" in next version gradient_unwarp_apply(WD=eddy_data_GDC, infile=eddy_data, outfile=eddy_data_ud, owarp=eddy_data_ud_warp, - gradcoeff=ctx.gdc, + gradcoeff=gdc, vendor='siemens', nojac=True, half=True) else: copyfile(src=eddy_data, dst=eddy_data_ud) diff --git a/bip/pipelines/dMRI_fieldmap/fieldmap_post_topup.py b/bip/pipelines/dMRI_fieldmap/fieldmap_post_topup.py index e419bc2..2e2c236 100755 --- a/bip/pipelines/dMRI_fieldmap/fieldmap_post_topup.py +++ b/bip/pipelines/dMRI_fieldmap/fieldmap_post_topup.py @@ -98,13 +98,15 @@ def run(ctx, wrappers.fslmaths(fieldmap_iout).Tmean().run(fieldmap_iout_mean) - if ctx.gdc != '': + gdc = ctx.get('gdc', None) + + if gdc not in (None, "", "none"): #Calculate and apply the Gradient Distortion Unwarp # TODO: Review the "half=True" in next version gradient_unwarp_apply(WD=fieldmap_GDC, infile=fieldmap_iout_mean, outfile=fieldmap_iout_mean_ud, owarp=fieldmap_iout_mean_ud_warp, - gradcoeff=ctx.gdc, + gradcoeff=gdc, vendor='siemens', nojac=True, half=True) else: copyfile(src=fieldmap_iout_mean, dst=fieldmap_iout_mean_ud) diff --git a/bip/pipelines/fMRI_rest/rfMRI_prepare.py b/bip/pipelines/fMRI_rest/rfMRI_prepare.py index 6f6fe4f..dbc3634 100755 --- a/bip/pipelines/fMRI_rest/rfMRI_prepare.py +++ b/bip/pipelines/fMRI_rest/rfMRI_prepare.py @@ -90,14 +90,16 @@ def run(ctx, if fieldName == "TE": fmriTE = fieldValue - if ctx.gdc != '': + gdc = ctx.get('gdc', None) + + if gdc not in (None, "", "none"): #Calculate and apply the Gradient Distortion Unwarp # TODO: Review the "half=True" in next version gradient_unwarp_apply(WD=rfMRI_SBREF_GDC, infile=rfMRI_SBREF, outfile=rfMRI_SBREF_ud, owarp=rfMRI_SBREF_ud_warp, - gradcoeff=ctx.gdc, + gradcoeff=gdc, vendor='siemens', nojac=True, half=False) else: copyfile(src=rfMRI_SBREF, dst=rfMRI_SBREF_ud) diff --git a/bip/pipelines/fMRI_task/tfMRI_prepare.py b/bip/pipelines/fMRI_task/tfMRI_prepare.py index aed25d0..f97c28c 100755 --- a/bip/pipelines/fMRI_task/tfMRI_prepare.py +++ b/bip/pipelines/fMRI_task/tfMRI_prepare.py @@ -89,14 +89,16 @@ def run(ctx, if fieldName == "TE": fmriTE = fieldValue - if ctx.gdc != '': + gdc = ctx.get('gdc', None) + + if gdc not in (None, "", "none"): #Calculate and apply the Gradient Distortion Unwarp # TODO: Review the "half=True" in next version gradient_unwarp_apply(WD=tfMRI_SBREF_GDC, infile=tfMRI_SBREF, outfile=tfMRI_SBREF_ud, owarp=tfMRI_SBREF_ud_warp, - gradcoeff=ctx.gdc, + gradcoeff=gdc, vendor='siemens', nojac=True, half=False) else: copyfile(src=tfMRI_SBREF, dst=tfMRI_SBREF_ud) diff --git a/bip/pipelines/struct_T1/T1_gdc.py b/bip/pipelines/struct_T1/T1_gdc.py index a39aed5..e070022 100755 --- a/bip/pipelines/struct_T1/T1_gdc.py +++ b/bip/pipelines/struct_T1/T1_gdc.py @@ -26,11 +26,13 @@ def run(ctx, with redirect_logging(job_name(run), outdir=logs_dir): - if ctx.gdc != '': + gdc = ctx.get('gdc', None) + + if gdc not in (None, "", "none"): #Calculate and apply the Gradient Distortion Unwarp # TODO: Review the "half=True" in next version gradient_unwarp_apply(WD=T1_GDC, infile=T1_orig, outfile=T1_orig_ud, - owarp=T1_orig_ud_warp,gradcoeff=ctx.gdc, + owarp=T1_orig_ud_warp, gradcoeff=gdc, vendor='siemens', nojac=True, half=True) else: copyfile(src=T1_orig, dst=T1_orig_ud) diff --git a/bip/pipelines/struct_T2_FLAIR/T2_FLAIR_gdc.py b/bip/pipelines/struct_T2_FLAIR/T2_FLAIR_gdc.py index d4d910b..21a1f77 100755 --- a/bip/pipelines/struct_T2_FLAIR/T2_FLAIR_gdc.py +++ b/bip/pipelines/struct_T2_FLAIR/T2_FLAIR_gdc.py @@ -27,12 +27,14 @@ def run(ctx, with redirect_logging(job_name(run), outdir=logs_dir): - if ctx.gdc != '': + gdc = ctx.get('gdc', None) + + if gdc not in (None, "", "none"): #Calculate and apply the Gradient Distortion Unwarp # TODO: Review the "half=True" in next version gradient_unwarp_apply(WD=T2_FLAIR_GDC, infile=T2_FLAIR_orig, outfile=T2_FLAIR_orig_ud, - owarp=T2_FLAIR_orig_ud_warp,gradcoeff=ctx.gdc, + owarp=T2_FLAIR_orig_ud_warp,gradcoeff=gdc, vendor='siemens', nojac=True, half=True) else: copyfile(src=T2_FLAIR_orig, dst=T2_FLAIR_orig_ud) diff --git a/bip/pipelines/struct_asl/asl_proc.py b/bip/pipelines/struct_asl/asl_proc.py index cfcf234..c697199 100755 --- a/bip/pipelines/struct_asl/asl_proc.py +++ b/bip/pipelines/struct_asl/asl_proc.py @@ -99,11 +99,13 @@ def run(ctx, rounding = 3, multFactor=1000) #Gradient distortion correction applied to the M0 - if ctx.gdc != '': + gdc = ctx.get('gdc', None) + + if gdc not in (None, "", "none"): #Calculate and apply the Gradient Distortion Unwarp # TODO: Review the "half=True" in next version gradient_unwarp_apply(WD=ASL_GDC, infile=CALIB, outfile=ASL_M0_ud, - owarp=ASL_M0_ud_warp,gradcoeff=ctx.gdc, + owarp=ASL_M0_ud_warp,gradcoeff=gdc, vendor='siemens', nojac=True, half=False) else: copyfile(src=CALIB, dst=ASL_M0_ud) diff --git a/bip/pipelines/struct_swMRI/swMRI_gdc.py b/bip/pipelines/struct_swMRI/swMRI_gdc.py index a0b7000..c9dd440 100755 --- a/bip/pipelines/struct_swMRI/swMRI_gdc.py +++ b/bip/pipelines/struct_swMRI/swMRI_gdc.py @@ -26,11 +26,13 @@ def run(ctx, with redirect_logging(job_name(run), outdir=logs_dir): - if ctx.gdc != '': + gdc = ctx.get('gdc', None) + + if gdc not in (None, "", "none"): #Calculate and apply the Gradient Distortion Unwarp # TODO: Review the "half=True" in next version gradient_unwarp_apply(WD=T1_GDC, infile=T1_orig, outfile=T1_orig_ud, - owarp=T1_orig_ud_warp,gradcoeff=ctx.gdc, + owarp=T1_orig_ud_warp,gradcoeff=gdc, vendor='siemens', nojac=True, half=True) else: copyfile(src=T1_orig, dst=T1_orig_ud) diff --git a/bip/pipelines/struct_swMRI/swMRI_proc.py b/bip/pipelines/struct_swMRI/swMRI_proc.py index e7552ab..fa73989 100755 --- a/bip/pipelines/struct_swMRI/swMRI_proc.py +++ b/bip/pipelines/struct_swMRI/swMRI_proc.py @@ -78,13 +78,14 @@ def run(ctx, gen_filtered_phase(ctx, MAG_TE2_dir, PHA_TE2_dir, SWI_MAG_TE2_orig, filtered_phase, SWI) - if ctx.gdc != '': + gdc = ctx.get('gdc', None) + if gdc not in (None, "", "none"): #Calculate and apply the Gradient Distortion Unwarp # TODO: Review the "half=True" in next version gradient_unwarp_apply(WD=SWI_GDC, infile=SWI_MAG_TE1_orig, outfile=SWI_MAG_TE1, owarp=SWI_TOTAL_MAG_orig_ud_warp, - gradcoeff=ctx.gdc, + gradcoeff=gdc, vendor='siemens', nojac=True, half=False) else: copyfile(src=SWI_MAG_TE1_orig, dst=SWI_MAG_TE1) diff --git a/bip/utils/__init__.py b/bip/utils/__init__.py index e97e100..6e6d67e 100644 --- a/bip/utils/__init__.py +++ b/bip/utils/__init__.py @@ -1,4 +1,9 @@ #!/usr/bin/env python +# +# pylint: disable=C0103,E0602,C0114,C0115,C0116,R0913,R0914,R0915 +# pylint: disable=W1203 +# + """The bip.utils package contains a range of miscellaneous utilities. """ @@ -7,6 +12,7 @@ import logging import os.path as op import os import time +import errno log = logging.getLogger(__name__) @@ -25,7 +31,7 @@ def lockdir(dirname, delay=5): while True: try: - log.debug(f'Attempting to lock %s for exclusive access.', dirname) + log.debug(f'Attempting to lock {dirname} for exclusive access.') fd = os.open(lockfile, os.O_CREAT | os.O_EXCL | os.O_RDWR) break except OSError as e: diff --git a/bip/utils/get_b0s.py b/bip/utils/get_b0s.py index a196947..7d341d7 100755 --- a/bip/utils/get_b0s.py +++ b/bip/utils/get_b0s.py @@ -1,11 +1,13 @@ -#!/bin/env python -''' - Authors: Fidel Alfaro Almagro - FMRIB, Oxford University - $01-May-2014 11:44:20$ - Version $1.0 - ProjectDir = - ''' +#!/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 sys import argparse import os.path @@ -13,7 +15,7 @@ from fsl import wrappers class MyParser(argparse.ArgumentParser): def error(self, message): - sys.stderr.write('error: %s\n' % message) + sys.stderr.write(f'error: {message}\n') self.print_help() sys.exit(2) @@ -21,7 +23,7 @@ class Usage(Exception): def __init__(self, msg): self.msg = msg -def get_b0s(inputFile, bvalFilename, outputFile, outputIndFile, desiredNumber, +def get_b0s(inputFile, bvalFilename, outputFile, outputIndFile, desiredNumber, B0limit=100): with open(bvalFilename, 'r', encoding="utf-8") as f: line = f.readlines() @@ -44,7 +46,8 @@ def main(): 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') + 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, @@ -73,7 +76,6 @@ def main(): else: bvalFilename = argsa.bvalFilename[0] - with open(bvalFilename, 'r', encoding="utf-8") as f: line = f.readlines() @@ -87,7 +89,8 @@ def main(): desiredNumber = argsa.desiredNumber[0] if desiredNumber > len(indices): - print(("There are only %i B0. It is not possible to have %i" % (len(indices), desiredNumber))) + print(f"There are only {len(indices)} B0. It is not possible " + \ + f"to have {desiredNumber}") sys.exit() if desiredNumber <= 0: diff --git a/bip/utils/get_dwell_time.py b/bip/utils/get_dwell_time.py index 339494a..50ec483 100755 --- a/bip/utils/get_dwell_time.py +++ b/bip/utils/get_dwell_time.py @@ -1,3 +1,14 @@ +#!/usr/bin/env python +# +# get_dwell_time.py - Utility to get the dwell time of a 4D image. +# +# 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 import nibabel as nib from bip.utils.read_json_field import read_json_field diff --git a/bip/utils/log_utils.py b/bip/utils/log_utils.py index 1ac4518..117bc76 100755 --- a/bip/utils/log_utils.py +++ b/bip/utils/log_utils.py @@ -7,7 +7,7 @@ # Author: Michiel Cottaar <michiel.cottaar@ndcn.ox.ac.uk> # # pylint: disable=C0103,E0602,C0114,C0115,C0116,R0913,R0914,R0915 -# pylint: disable=W0613 +# pylint: disable=W0613,W1203,W0631 # import os import os.path as op @@ -21,8 +21,7 @@ import functools as ft from subprocess import check_output from fsl import wrappers - -def run_command(logger, command, **kwargs): +def run_command(logger, command, **kwargs): try: logger.info(command.strip()) job_output = check_output(command,shell=True,**kwargs).decode('UTF-8') diff --git a/bip/utils/read_json_field.py b/bip/utils/read_json_field.py index d5f3f7a..cdfb11a 100755 --- a/bip/utils/read_json_field.py +++ b/bip/utils/read_json_field.py @@ -1,11 +1,14 @@ -#!/bin/env python -''' - Authors: Fidel Alfaro Almagro - FMRIB, Oxford University - $15-Dec-2014 10:41:10$ - Version $1.0 - ProjectDir = - ''' +#!/usr/bin/env python +# +# read_json_field.py - Utility to read json fields. +# +# 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 sys import json import numbers @@ -14,7 +17,7 @@ import argparse class MyParser(argparse.ArgumentParser): def error(self, message): - sys.stderr.write('error: %s\n' % message) + sys.stderr.write(f'error: {message}\n') self.print_help() sys.exit(2) @@ -49,7 +52,8 @@ def main(): parser.add_argument('-f', dest="field", type=str, nargs=1, default="NONE", help='Read field') parser.add_argument('-r', dest="rounding", type=int, default=0, - help='Round the value the selected number of decimals (Default: No rounding') + help='Round the value the selected number of decimals'+\ + ' (Default: No rounding') parser.add_argument('-m', dest="multFactor", type=float, default=1, help='Multiplication factor for the selected value (Default 1)') -- GitLab