Source code for mcutils.scripts.sidecar.index

#!/usr/bin/env python
"""Indexes the volumes into shells based on the sidecar"""
import argparse
import logging
from mcutils.utils.sidecar import AcquisitionParams
import numpy as np

logger = logging.getLogger(__name__)

possible_parameters = [
    ('b', 'b-value (in s/mm^2)'),
    ('b_delta', 'anisotropy of b-tensor'),
    ('b_eta', 'asymmetry of b-tensor'),
    ('b_symm', 'b-value along symmetry axis'),
    ('b_perp', 'b-value perpendicular to the symmetry axis'),
    ('te', 'echo time'),
    ('tr', 'repetition time'),
    ('ti', 'inversion time'),
    ('tm', 'mixing time'),
]


[docs]def get_indices(sidecar: AcquisitionParams, group_args): """ Assigns each observation to a shell :param sidecar: MDE XPS structure describing the data :param group_args: command line arguments from scripts.sidecar_index.add_index_params :return: integer array with the shell index """ constraints = { var: getattr(group_args, var) for var, _ in possible_parameters if getattr(group_args, var, None) is not None } for idx, (var, value) in enumerate(constraints.items()): logger.debug(f'Constraint #{idx + 1}: Delta {var} <= {value}') indices = sidecar.get_index(**constraints, sort_by=group_args.sort) logger.info(f'{max(indices) + 1} shells found') logger.debug(f'Shell indices (0-based): {list(indices)}') for idx, var in enumerate(constraints.keys()): values = sidecar[var] logger.debug(f'Mean {var} per shell: {[np.mean(values[idx == indices]) for idx in range(max(indices) + 1)]}') return indices
[docs]def run_from_args(args): """ Runs the script based on a Namespace containing the command line arguments """ sidecar = AcquisitionParams.read(args.input) indices = get_indices(sidecar, group_args=args) if args.a_ind: sidecar.a_ind = indices elif args.s_ind: sidecar.s_ind = indices else: raise ValueError("either --a_ind or --s_ind should be set") out_fn = args.input if args.output is None else args.output sidecar.write(out_fn)
[docs]def add_index_params(parser: argparse.ArgumentParser, exclude=(), as_group=True): """ Adds the arguments needed to define indexing of an XPS file on the command line :param parser: argument parser :param exclude: exclude certain parameters from the accepted parameter list :param as_group: add the new parameters in their own group """ if as_group: group = parser.add_argument_group('indexing', 'Parameters used to group the data into different shells.\n' + 'Any observations that match for all parameters within the provided ' + 'offsets will be in the same shell.') else: group = parser for var, description in possible_parameters: if var not in exclude: group.add_argument(f'--{var}', type=float, help='maximum offset for ' + description) parser.add_argument('--sort', choices=[p[0] for p in possible_parameters], help='sort the output by the selected parameter')
[docs]def add_to_parser(parser): """ Creates the parser of the command line arguments """ parser.add_argument("input", help='Sidecar input file with acquisition parameters (.mat or .json)') parser.add_argument("output", nargs='?', help='Sidecar output file (.mat or .json). Defaults to the input file') target_group = parser.add_mutually_exclusive_group(required=True) target_group.add_argument('-a', '--a_ind', help='add shell index to the a_ind index', action='store_true') target_group.add_argument('-s', '--s_ind', help='add shell index to the s_ind index', action='store_true') add_index_params(parser)