def main(): # :: handle program parameters arg_parser = handle_arg() args = arg_parser.parse_args() # fix verbosity in case of 'quiet' if args.quiet: args.verbose = VERB_LVL['none'] # :: print debug info if args.verbose >= VERB_LVL['debug']: arg_parser.print_help() msg('\nARGS: ' + str(vars(args)), args.verbose, VERB_LVL['debug']) if not args.name: msg('Choose your playground:') msg('Available playgrounds: {AVAILABLES}'.format_map(globals())) args.name = input(': ') if args.name in AVAILABLES: numex.interactive_tk_mpl.plotting(globals()[PREFIX + args.name], PARAMS[args.name], title=TITLE_BASE + ' - ' + TITLE[args.name], about=__doc__) elapsed(__file__[len(PATH['base']) + 1:]) msg(report()) else: msg(fmtm('Plot `{args.name}` not valid.'))
def dphs_to_phs(dphs_arr, tis, phs0_arr=0, time_units='ms'): """ Calculate the phase variation from phase data. Args: dphs_arr (np.ndarray): The input array in rad. The sampling time Ti varies in the last dimension. tis (Iterable|int|float): The sampling times Ti in time units. The number of points will match the last shape size of `phs_arr`. phs0_arr (np.ndarray|int|float): The initial phase offset. If int or float, a constant offset is used. time_units (str|float|int): Units of measurement of Ti. If str, any valid SI time unit (e.g. `ms`, `ns`) will be accepted. If int or float, the conversion factor will be multiplied to `ti`. Returns: phs_arr (np.ndarray): The phase array in rad. """ units_factor = 1 if isinstance(time_units, str) and 's' in time_units: prefix, _ = time_units.split('s', 1) units_factor = fc.prefix_to_factor(prefix) elif isinstance(time_units, (int, float)): units_factor = time_units else: warnings.warn(fmtm('Invalid units `{time_units}`. Ignored.')) shape = dphs_arr.shape tis = np.array(fc.auto_repeat(tis, 1)) * units_factor tis = tis.reshape((1, ) * len(shape) + (-1, )) dphs_arr = dphs_arr.reshape(shape + (1, )) return dphs_arr * tis + phs0_arr
def cx2_to_dphs(arr1, arr2, d_ti, unwrap_method='laplacian_c', unwrap_kws=None, time_units='ms'): """ Calculate the phase variation from two complex data. Args: arr1 (np.ndarray): The phase array for sampling time 1 in arb. units. Arbitrary units are accepted, will be automatically converted to radians under the assumption that data is wrapped. Do not provide unwrapped data. Shape must match that of `arr2`. arr2 (np.ndarray): The phase array for sampling time 2 in arb. units. Arbitrary units are accepted, will be automatically converted to radians under the assumption that data is wrapped. Do not provide unwrapped data. Shape must match that of `arr1`. d_ti (int|float): The sampling time differenct in time units. unwrap_method (str|None): The unwrap method. See `pymrt.recipes.phs.unwrap()` for details. unwrap_kws (Mappable|None): Keyword arguments for `unwrap()`. time_units (str|float|int): Units of measurement of Ti. If str, any valid SI time unit (e.g. `ms`, `ns`) will be accepted. If int or float, the conversion factor will be multiplied to `ti`. Returns: dphs_arr (np.ndarray): The phase variation in rad/s. """ units_factor = 1 if isinstance(time_units, str) and 's' in time_units: prefix, _ = time_units.split('s', 1) units_factor = fc.prefix_to_factor(prefix) elif isinstance(time_units, (int, float)): units_factor = time_units else: warnings.warn(fmtm('Invalid units `{time_units}`. Ignored.')) dphs_arr = arr1 * arr2.conj() dphs_arr = np.arctan2(np.imag(dphs_arr), np.real(dphs_arr)) if unwrap is not None: dphs_arr = unwrap(dphs_arr, unwrap_method, unwrap_kws) return dphs_arr / (d_ti * units_factor)
def handle_arg(): """ Handle command-line application arguments. """ # :: Create Argument Parser arg_parser = argparse.ArgumentParser( description=__doc__, epilog=fmtm('v.{version} - {author}\n{license}', INFO), formatter_class=argparse.RawDescriptionHelpFormatter) # :: Add POSIX standard arguments arg_parser.add_argument( '--ver', '--version', version=fmt( '%(prog)s - ver. {version}\n{}\n{copyright} {author}\n{notice}', next(line for line in __doc__.splitlines() if line), **INFO), action='version') arg_parser.add_argument( '-v', '--verbose', action='count', default=D_VERB_LVL, help='increase the level of verbosity [%(default)s]') arg_parser.add_argument( '-q', '--quiet', action='store_true', help='override verbosity settings to suppress output [%(default)s]') # :: Add additional arguments arg_parser.add_argument('--t1', metavar='X', type=float, default=1000, help='set the T1 value in ms [%(default)s]') arg_parser.add_argument('--tr', metavar='X', type=float, default=100, help='set the TR value in ms [%(default)s]') arg_parser.add_argument('--fa', metavar='X', type=float, default=None, help='set the FA value in deg [%(default)s]') return arg_parser
def handle_arg(): """ Handle command-line application arguments. """ # :: Create Argument Parser arg_parser = argparse.ArgumentParser( description=__doc__, epilog=fmtm('v.{version} - {author}\n{license}', INFO), formatter_class=argparse.RawDescriptionHelpFormatter) # :: Add POSIX standard arguments arg_parser.add_argument( '--ver', '--version', version=fmt( '%(prog)s - ver. {version}\n{}\n{copyright} {author}\n{notice}', next(line for line in __doc__.splitlines() if line), **INFO), action='version') arg_parser.add_argument( '-v', '--verbose', action='count', default=D_VERB_LVL, help='increase the level of verbosity [%(default)s]') arg_parser.add_argument( '-q', '--quiet', action='store_true', help='override verbosity settings to suppress output [%(default)s]') # :: Add additional arguments arg_parser.add_argument('-f', '--force', action='store_true', help='force new processing [%(default)s]') arg_parser.add_argument('-d', '--dir', metavar='DIR', default='.', help='set working directory [%(default)s]') arg_parser.add_argument('-e', '--extradir', metavar='FOLDER', default='nifti', help='set output subdirectory [%(default)s]') return arg_parser
def threshold_to_mask(arr, threshold, comparison='>'): """ Apply the specified threshold to the array. Args: arr (np.ndarray): Input array for the masking. threshold (int|float): Value for the threshold. comparison (str): A string representing the numeric relationship Accepted values are: ['==', '!=', '>', '<', '>=', '<='] Returns: mask (np.ndarray[bool]): Mask for which comparison is True. """ # for security reasons comparison is checked before eval comparisons = ('==', '!=', '>', '<', '>=', '<=') if comparison in comparisons: mask = eval('arr {c} threshold'.format(c=comparison)) else: raise ValueError( fmtm('valid comparisons are: {comparisons} (given: {comparison})')) return mask
def simple_filter_1_x(in_filepath, out_basepath, func, out_filename_template='{base}_{name}{ext}', *_args, **_kws): """ Interface to simplified n-m filter. filter(in_filepaths) -> out_filepaths Args: in_filepath (str): Input file path The metadata information is taken from the input. out_basepath (str): Base output directory path. Additional subdirectories can be specified through the `out_filename_template` parameter. out_filename_template (str): If subdirectories do not exists, they are created. The following substitution are valid: - `{path}`: the input directory path. - `{base}`: the input file name without extension. - `{ext}`: the input file extension. - `{name}`: the result identifier from the computing function. func (callable): Filtering function (arr: ndarray) func(list[arr], *_args, *kws) -> list[ndarray] *_args: Positional arguments of the filtering function **_kws: Keyword arguments of the filtering function Returns: None. """ arr, meta = load(in_filepath, meta=True) results = func(arr, *_args, **_kws) path, base, ext = fc.split_path(in_filepath) for i, (name, arr) in enumerate(results.items()): out_filepath = os.path.join(out_basepath, fmtm(out_filename_template)) out_dirpath = os.path.dirname(out_filepath) if not os.path.isdir(out_dirpath): os.makedirs(out_dirpath) save(out_filepath, arr, **meta)
def handle_arg(): """ Handle command-line application arguments. """ # :: Create Argument Parser arg_parser = argparse.ArgumentParser( description=__doc__, epilog=fmtm('v.{version} - {author}\n{license}', INFO), formatter_class=argparse.RawDescriptionHelpFormatter) # :: Add POSIX standard arguments arg_parser.add_argument( '--ver', '--version', version=fmt( '%(prog)s - ver. {version}\n{}\n{copyright} {author}\n{notice}', next(line for line in __doc__.splitlines() if line), **INFO), action='version') arg_parser.add_argument( '-v', '--verbose', action='count', default=D_VERB_LVL, help='increase the level of verbosity [%(default)s]') arg_parser.add_argument( '-q', '--quiet', action='store_true', help='override verbosity settings to suppress output [%(default)s]') # :: Add additional arguments arg_parser.add_argument( '-n', '--name', metavar='NAME', default=None, choices=AVAILABLES, help='playground selection (from: %(choices)s) [%(default)s]') return arg_parser
def noise(raw_arr, reco_func, reco_args=None, reco_kws=None, noise_level=1, num=64, verbose=D_VERB_LVL): """ Estimate the noise for reco using a pseudo-multi-replica approach. This a Monte Carlo method, effectively consisting of computing the standard deviation for multiple instances of the image reconstructed after the addition of white noise in the complex raw data. This is can be used to compute the signal-to-noise (SNR) and the geometric noise amplification factor (g-factor). The SNR can be computed by: snr = reco_arr / noise_arr with: reco_arr = reco_func(raw_arr, *reco_args, **reco_kws) Args: raw_arr (np.ndarray): The input raw data as acquired (k-space). reco_func (callable): The reconstruction function. Must accept the raw data array as first argument. reco_args (Iterable|None): Positional arguments for `reco_func`. reco_kws (Mappable|None): Keyword arguments for `reco_func`. noise_level (int|float|str|None): The noise level. This is used to determine the st.dev of the Gaussian noise being added at each iteration. If int or float, the value is the st.dev of the Gaussian noise. If str and the value is a percentage, the st.dev is computed as the peak-to-peak value multiplied by `noise_level` percentage (the peak-to-peak value is the maximum of the peak-to-peak value for real and imaginary data separately). If None, the noise level is estimated using `pymrt.correction.estimate_noise_sigma()`. num (int): The number of repetitions. verbose (int): Set level of verbosity. Returns: result (tuple): The tuple contains: - noise_arr (np.ndarray): The st.dev. of noised reconstructions. - reco_arr (np.ndarray): The reco from data without extra noise. """ reco_args = tuple(reco_args) if reco_args else () reco_kws = dict(reco_kws) if reco_kws else {} # noise-less reco reco_arr = reco_func(raw_arr, *reco_args, **reco_kws) # compute desired noise std if noise_level is None: noise_std_val = mrt.correction.estimate_noise_sigma(raw_arr) elif isinstance(noise_level, (int, float)): noise_std_val = noise_level else: noise_std_val = fc.to_percent(noise_level) if noise_std_val: cx_ptp = max(np.ptp(np.real(raw_arr)), np.ptp(np.imag(raw_arr))) noise_std_val = cx_ptp * noise_std_val else: noise_std_val = 1 msg(fmtm('Noise St.Dev.: {noise_std_val} (Level: {noise_level})'), verbose, VERB_LVL['debug']) mean_noised_arr = np.zeros_like(reco_arr, dtype=float) sosd_noised_arr = np.zeros_like(reco_arr, dtype=float) for i in range(num): msg(fmtm('Replica #{i}'), verbose, VERB_LVL['debug']) noise_raw_arr = np.random.normal(0, noise_std_val, raw_arr.shape) noised_arr = reco_func(raw_arr + noise_raw_arr, *reco_args, **reco_kws) mean_noised_arr, sosd_noised_arr, _ = fc.next_mean_and_sosd( np.real(noised_arr), mean_noised_arr, sosd_noised_arr, i) noise_arr = fc.sosd2stdev(sosd_noised_arr, num) return noise_arr, reco_arr
def handle_arg(): """ Handle command-line application arguments. """ # :: Create Argument Parser arg_parser = argparse.ArgumentParser( description=__doc__, epilog=fmtm('v.{version} - {author}\n{license}', INFO), formatter_class=argparse.RawDescriptionHelpFormatter) # :: Add POSIX standard arguments arg_parser.add_argument( '--ver', '--version', version=fmt( '%(prog)s - ver. {version}\n{}\n{copyright} {author}\n{notice}', next(line for line in __doc__.splitlines() if line), **INFO), action='version') arg_parser.add_argument( '-v', '--verbose', action='count', default=D_VERB_LVL, help='increase the level of verbosity [%(default)s]') arg_parser.add_argument( '-q', '--quiet', action='store_true', help='override verbosity settings to suppress output [%(default)s]') # :: Add additional arguments arg_parser.add_argument('-f', '--force', action='store_true', help='force new processing [%(default)s]') arg_parser.add_argument('-d', '--dirpath', metavar='DIR', default='.', help='set working directory [%(default)s]') arg_parser.add_argument('-n', '--val_name', metavar='NAME', default=None, help='set values name ( [%(default)s]') arg_parser.add_argument('-a', '--val_interval', metavar=('MIN', 'MAX'), type=float, nargs=2, default=None, help='set interval of values [%(default)s]') arg_parser.add_argument('-u', '--val_units', metavar='UNITS', default=None, help='set units for values [%(default)s]') arg_parser.add_argument('-m', '--mask_filepath', metavar='FILE', default=None, help='set exact mask file [%(default)s]') arg_parser.add_argument( '--reg_ref_ext', metavar='FILE_EXT', default=pml.EXT['reg_ref'], help='file extension of registration reference flag [%(default)s]') arg_parser.add_argument( '--corr_ref_ext', metavar='FILE_EXT', default=pml.EXT['corr_ref'], help='file extension of correlation reference flag [%(default)s]') arg_parser.add_argument( '--tmp_dir', metavar='SUBDIR', default='tmp', help='subdirectory where to store temporary files [%(default)s]') arg_parser.add_argument( '--reg_dir', metavar='SUBDIR', default='reg', help='subdirectory where to store registration files [%(default)s]') arg_parser.add_argument( '--msk_dir', metavar='SUBDIR', default='msk', help='subdirectory where to store masking files [%(default)s]') arg_parser.add_argument( '--cmp_dir', metavar='SUBDIR', default='cmp', help='subdirectory where to store comparing files [%(default)s]') arg_parser.add_argument( '--fig_dir', metavar='SUBDIR', default='fig', help='subdirectory where to store figures [%(default)s]') return arg_parser
def handle_arg(): """ Handle command-line application arguments. """ # :: Create Argument Parser arg_parser = argparse.ArgumentParser( description=__doc__, epilog=fmtm('v.{version} - {author}\n{license}', INFO), formatter_class=argparse.RawDescriptionHelpFormatter) # :: Add POSIX standard arguments arg_parser.add_argument( '--ver', '--version', version=fmt( '%(prog)s - ver. {version}\n{}\n{copyright} {author}\n{notice}', next(line for line in __doc__.splitlines() if line), **INFO), action='version') arg_parser.add_argument( '-v', '--verbose', action='count', default=D_VERB_LVL, help='increase the level of verbosity [%(default)s]') arg_parser.add_argument( '-q', '--quiet', action='store_true', help='override verbosity settings to suppress output [%(default)s]') # :: Add additional arguments arg_parser.add_argument('-f', '--force', action='store_true', help='force new processing [%(default)s]') arg_parser.add_argument( '-i', '--in_filepaths', metavar=('MAG_FILE', 'PHS_FILE'), nargs=2, default=('mag_coils.nii.gz', 'phs_coils.nii.gz'), help='set input magnitude and phase filepaths [%(default)s]') arg_parser.add_argument( '-o', '--out_filepaths', metavar=('MAG_FILE', 'PHS_FILE'), nargs=2, default=('mag.nii.gz', 'phs.nii.gz'), help='set output magnitude and phase filepaths [%(default)s]') arg_parser.add_argument( '-p', '--q_filepath', metavar='FILE', default=None, help='set output quality metric filepath [%(default)s]') arg_parser.add_argument('-m', '--method', metavar='STR', default='block_adaptive_iter', help=' [%(default)s]') arg_parser.add_argument( '-mk', '--method_kws', metavar='STR', default=None, help='Additional keyword parameters for the method [%(default)s]') arg_parser.add_argument('-c', '--compression', metavar='STR', default='compress_svd', help=' [%(default)s]') arg_parser.add_argument( '-ck', '--compression_kws', metavar='STR', default=None, help='Additional keyword parameters for the compression [%(default)s]') arg_parser.add_argument( '-a', '--coil_axis', metavar='N', default=-1, help='Axis along which the single coils are stored [%(default)s]') arg_parser.add_argument( '-s', '--split_axis', metavar='N', default=None, help='Axis along which input shall be split [%(default)s]') return arg_parser
def batch_extract( dirpath, out_filename='niz/{scan_num}__{acq_method}_{scan_name}_{reco_flag}', out_dirpath=None, custom_reco=None, custom_reco_kws=None, fid_name='fid', dseq_name='2dseq', acqp_name='acqp', method_name='method', reco_name='reco', allowed_ext=('', 'gz'), force=False, verbose=D_VERB_LVL): """ Extract images from experiment folder. EXPERIMENTAL! Args: dirpath (str): out_filename (str|None): out_dirpath (str|None): custom_reco (str|None): Determines how results will be saved. Accepted values are: - 'mag_phs': saves magnitude and phase. - 're_im': saves real and imaginary parts. - 'cx': saves the complex data. custom_reco_kws (Mappable|None): fid_name (): dseq_name (): acqp_name (): method_name (): reco_name (): allowed_ext (): force (): verbose (): Returns: """ text = '\n'.join( ('EXPERIMENTAL!', 'Use at your own risk!', 'Known issues:', ' - orientation not adjusted to method (i.e. 0->RO, 1->PE, 2->SL)', ' - FOV is centered out', ' - voxel size is not set', '')) warnings.warn(text) if allowed_ext is None: allowed_ext = '' elif isinstance(allowed_ext, str): allowed_ext = (allowed_ext, ) fid_filepaths = sorted( fc.flistdir(_to_patterns(fid_name, allowed_ext), dirpath)) for fid_filepath in sorted(fid_filepaths): msg('FID: {}'.format(fid_filepath), verbose, D_VERB_LVL) fid_dirpath = os.path.dirname(fid_filepath) if out_dirpath is None: out_dirpath = dirpath out_filepath = os.path.join(out_dirpath, out_filename) acqp_filepath = _get_single(fid_dirpath, acqp_name, allowed_ext) method_filepath = _get_single(fid_dirpath, method_name, allowed_ext) dseq_filepaths = sorted( fc.flistdir(_to_patterns(dseq_name, allowed_ext), fid_dirpath)) reco_filepaths = sorted( fc.flistdir(_to_patterns(reco_name, allowed_ext), fid_dirpath)) acqp_s, acqp, acqp_c = jcampdx.read(acqp_filepath) method_s, method, method_c = jcampdx.read(method_filepath) scan_num, sample_id = _get_scan_num_sample_id(acqp_c) scan_name = fc.safe_filename(acqp['ACQ_scan_name']) acq_method = fc.safe_filename(acqp['ACQ_method']) reco_flag = mrt.naming.NEW_RECO_ID if custom_reco: load_info = _get_load_bin_info_fid(acqp, method) if custom_reco == 'cx': reco_flag = mrt.naming.ITYPES['cx'] cx_filepath = fc.change_ext(fmtm(out_filepath), mrt.util.EXT['niz']) if not os.path.isdir(os.path.dirname(cx_filepath)): os.makedirs(os.path.dirname(cx_filepath)) if fc.check_redo( [fid_filepath, acqp_filepath, method_filepath], [cx_filepath], force): arr = _load_bin(fid_filepath, **load_info) arr = _reco_from_fid(arr, acqp, method, verbose=verbose) mrt.input_output.save(cx_filepath, arr) msg('CX: {}'.format(os.path.basename(cx_filepath)), verbose, D_VERB_LVL) elif custom_reco == 'mag_phs': reco_flag = mrt.naming.ITYPES['mag'] mag_filepath = fc.change_ext(fmtm(out_filepath), mrt.util.EXT['niz']) if not os.path.isdir(os.path.dirname(mag_filepath)): os.makedirs(os.path.dirname(mag_filepath)) reco_flag = mrt.naming.ITYPES['phs'] phs_filepath = fc.change_ext(fmtm(out_filepath), mrt.util.EXT['niz']) if not os.path.isdir(os.path.dirname(phs_filepath)): os.makedirs(os.path.dirname(phs_filepath)) if fc.check_redo( [fid_filepath, acqp_filepath, method_filepath], [mag_filepath, phs_filepath], force): reco_flag = mrt.naming.ITYPES['mag'] arr = _load_bin(fid_filepath, **load_info) arr = _reco_from_fid(arr, acqp, method, verbose=verbose) mrt.input_output.save(mag_filepath, np.abs(arr)) msg('MAG: {}'.format(os.path.basename(mag_filepath)), verbose, D_VERB_LVL) mrt.input_output.save(phs_filepath, np.angle(arr)) msg('PHS: {}'.format(os.path.basename(phs_filepath)), verbose, D_VERB_LVL) elif custom_reco == 're_im': reco_flag = mrt.naming.ITYPES['re'] re_filepath = fc.change_ext(fmtm(out_filepath), mrt.util.EXT['niz']) if not os.path.isdir(os.path.dirname(re_filepath)): os.makedirs(os.path.dirname(re_filepath)) reco_flag = mrt.naming.ITYPES['im'] im_filepath = fc.change_ext(fmtm(out_filepath), mrt.util.EXT['niz']) if not os.path.isdir(os.path.dirname(im_filepath)): os.makedirs(os.path.dirname(im_filepath)) if fc.check_redo( [fid_filepath, acqp_filepath, method_filepath], [re_filepath, im_filepath], force): arr = _load_bin(fid_filepath, **load_info) arr = _reco_from_fid(arr, acqp, method, verbose=verbose) mrt.input_output.save(re_filepath, np.abs(arr)) msg('RE: {}'.format(os.path.basename(re_filepath)), verbose, D_VERB_LVL) mrt.input_output.save(im_filepath, np.angle(arr)) msg('IM: {}'.format(os.path.basename(im_filepath)), verbose, D_VERB_LVL) else: text = 'Voxel data and shapes may be incorrect.' warnings.warn(text) for dseq_filepath, reco_filepath \ in zip(dseq_filepaths, reco_filepaths): reco_s, reco, reco_c = jcampdx.read(reco_filepath) reco_flag = _get_reco_num(reco_c) cx_filepath = fc.change_ext(fmtm(out_filepath), mrt.util.EXT['niz']) if not os.path.isdir(os.path.dirname(cx_filepath)): os.makedirs(os.path.dirname(cx_filepath)) load_info = _get_load_bin_info_reco(reco, method) if fc.check_redo([dseq_filepath, reco_filepath], [cx_filepath], force): arr = _load_bin(dseq_filepath, **load_info) arr = _reco_from_bin(arr, reco, method, verbose=verbose) mrt.input_output.save(cx_filepath, arr) msg('NIZ: {}'.format(os.path.basename(cx_filepath)), verbose, D_VERB_LVL)
def auto_convert(filepaths, out_template='{basepath}__{name}.nii.gz', save_kws=None, on_exist='unique', verbose=D_VERB_LVL): """ Automatically convert MATLAB data to PyMRT's standard format (NIfTI). Args: filepaths (Iterable[str]): List of filepaths to convert. Can be combined with file listing functions from `pymrt.utils`, e.g. `iflistdir()`, `flistdir()`, `listdir()` (directly) or `iwalk2()`, `walk2()` (indirectly). out_template (str): Template for the output filepath. The following variables are available for interpolation: - `dirpath`: The directory of the input. - `base`: The input base file name without extension. - `ext`: The input file extension (with leading separator). - `basepath`: The input filepath without extension. - `name`: The name of the variable as stored in the MATLAB file. save_kws (Mappable|None): Keyword parameters for `input_output.save()`. on_exist (str): Determine what to do if output exists. Accepted values are: - 'unique': Generate a new unique filepath. - 'skip': Skip saving the data. - 'overwrite': Overwrites the data onto existing filepath! verbose (int): Set level of verbosity. Returns: None. """ if save_kws is None: save_kws = {} on_exist = on_exist.lower() for in_filepath in filepaths: if os.path.isfile(in_filepath): msg('Loading: {}'.format(in_filepath), verbose, D_VERB_LVL) for name, arr in read(in_filepath, verbose=verbose).items(): dirpath, base, ext = fc.split_path(in_filepath) basepath = os.path.join(dirpath, base) out_filepath = fmtm(out_template) do_save = True if os.path.exists(out_filepath): if on_exist == 'skip': do_save = False elif on_exist == 'overwrite': pass else: if on_exist != 'unique': text = 'Unknown value `{}` for `on_exist`. ' \ 'Default to `unique`.' warnings.warn(text) out_filepath = fc.next_filepath(out_filepath) if do_save: msg('Saving: {}'.format(out_filepath), verbose, D_VERB_LVL) try: mrt.input_output.save(out_filepath, arr, **save_kws) except ValueError: msg('W: Saving failed!'.format(out_filepath), verbose, D_VERB_LVL) else: msg('Skip: {}'.format(out_filepath), verbose, D_VERB_LVL)
def phs_to_dphs(phs_arr, tis, tis_mask=None, unwrapping='laplacian', unwrapping_kws=None, time_units='ms'): """ Calculate the phase variation from phase data. Args: phs_arr (np.ndarray): The input array in arb. units. The sampling time Ti varies in the last dimension. Arbitrary units are accepted, will be automatically converted to radians under the assumption that data is wrapped. Do not provide unwrapped data. tis (Iterable|int|float): The sampling times Ti in time units. The number of points must match the last shape size of arr. tis_mask (Iterable[bool]|None): Determine the sampling times Ti to use. If None, all will be used. unwrapping (str|None): The unwrap method. If None, no unwrap is performed. If str, perform unwrap using `pymrt.recipes.phs.unwrap()`. Accepted values are: - 'auto': uses the best method for the given input. If `len(tis) == 1` use `pymrt.recipes.phs.unwrap_sorting_path()`, otherwise use `pymrt.recipes.phs.unwrap_laplacian()`. - 'laplacian': use `pymrt.recipes.phs.unwrap_laplacian()`. - 'sorting_path': use `pymrt.recipes.phs.unwrap_sorting_path()`. unwrapping_kws (Mappable|None): Additional keyword arguments. These are passed to `pymrt.recipes.phs.unwrap()`. time_units (str|float|int): Units of measurement of Ti. If str, any valid SI time unit (e.g. `ms`, `ns`) will be accepted. If int or float, the conversion factor will be multiplied to `ti`. Returns: dphs_arr (np.ndarray): The phase variation in rad/s. """ units_factor = 1 if isinstance(time_units, str) and 's' in time_units: prefix, _ = time_units.split('s', 1) units_factor = fc.prefix_to_factor(prefix) elif isinstance(time_units, (int, float)): units_factor = time_units else: warnings.warn(fmtm('Invalid units `{time_units}`. Ignored.')) tis = np.array(fc.auto_repeat(tis, 1)) * units_factor if unwrapping is not None: phs_arr = unwrap(phs_arr, unwrapping, unwrapping_kws) if len(tis) == 1: dphs_arr = phs_arr / tis[0] else: dphs_arr = \ phs_to_dphs_multi( phs_arr, tis, tis_mask, poly_deg=1, time_units='s') \ ['dphs_1'][..., 0] return dphs_arr
def handle_arg(): """ Handle command-line application arguments. """ # :: Create Argument Parser arg_parser = argparse.ArgumentParser( description=__doc__, epilog=fmtm('v.{version} - {author}\n{license}', INFO), formatter_class=argparse.RawDescriptionHelpFormatter) # :: Add POSIX standard arguments arg_parser.add_argument( '--ver', '--version', version=fmt( '%(prog)s - ver. {version}\n{}\n{copyright} {author}\n{notice}', next(line for line in __doc__.splitlines() if line), **INFO), action='version') arg_parser.add_argument( '-v', '--verbose', action='count', default=D_VERB_LVL, help='increase the level of verbosity [%(default)s]') arg_parser.add_argument( '-q', '--quiet', action='store_true', help='override verbosity settings to suppress output [%(default)s]') # :: Add additional arguments arg_parser.add_argument('-f', '--force', action='store_true', help='force new processing [%(default)s]') arg_parser.add_argument('-i', '--input', metavar='DIR', default='.', help='set input directory [%(default)s]') arg_parser.add_argument('-o', '--output', metavar='DIR', default='.', help='set output directory [%(default)s]') arg_parser.add_argument( '-r', '--recursive', action='store_true', help='Force descending into subdirectories [%(default)s]') arg_parser.add_argument('-e', '--meta_subpath', metavar='DIR', default=pmc.META_EXT, help='set extra input subdirectory [%(default)s]') arg_parser.add_argument('-a', '--data_subpath', metavar='DIR', default='nii', help='set extra input subdirectory [%(default)s]') arg_parser.add_argument( '-m', '--method', metavar='METHOD', default='generic', help='set computation target and method [%(default)s]') arg_parser.add_argument( '-n', '--options', metavar='OPTS', default='{}', help='set JSON-formatted options dictionary [%(default)s]') return arg_parser
def to_image(html_code, save_filepath, method=None, html_filepath=True, img_type='png', dpi=96, trim=True, force=False, verbose=D_VERB_LVL): """ Render a HTML page to an image. Args: html_code (str): The HTML code to render. save_filepath (str): The image file. method (str|None): The HTML-to-image method html_filepath (str|bool|None): The intermediate HTML file. img_type (str): The image type / extension of the output. dpi (int|float): The image density of the output. trim (bool): Remove borders from the image. force (bool): Force calculation of output. verbose (int): Set level of verbosity. Returns: None. """ available_methods = [] if shutil.which('wkhtmltoimage'): available_methods.append('webkit-png') if shutil.which('wkhtmltopdf'): available_methods.append('webkit-pdf') try: import weasyprint except ImportError: weasyprint = None else: available_methods.append('weasyprint') if not method: method = available_methods[0] # export intermediate HTML output if html_filepath is True or method.startswith('webkit-'): html_filepath = fc.change_ext(save_filepath, 'htm') if html_filepath: with open(html_filepath, 'wb+') as file_obj: file_obj.write(html_code.encode('ascii', 'xmlcharrefreplace')) if method.startswith('webkit-'): d_webkit_dpi = 96 d_webkit_width = 1024 zoom = dpi / d_webkit_dpi width = int(zoom * d_webkit_width) if img_type.lower() == 'png': webkit_cmd = 'wkhtmltoimage' elif img_type.lower() == 'pdf': webkit_cmd = 'wkhtmltopdf' os.system( fmtm('{webkit_cmd} --encoding UTF-8 --zoom {zoom} --width {width} ' ' "{html_filepath}" "{save_filepath}"')) elif method == 'weasyprint': html_obj = weasyprint.HTML(string=html_code) if img_type.lower() == 'png': html_obj.write_png(save_filepath) elif img_type.lower() == 'pdf': html_obj.write_pdf(save_filepath) if img_type.lower() == 'png' and trim: _trim(save_filepath)
def phs_to_dphs_multi(phs_arr, tis, tis_mask=None, poly_deg=1, full=False, time_units='s'): """ Calculate the polynomial components of the phase variation from phase data. Args: phs_arr (np.ndarray): The input array in rad. The sampling time Ti varies in the last dimension. The data is assumed to be already unwrapped. tis (Iterable): The sampling times Ti in time units. The number of points must match the last shape size of arr. tis_mask (Iterable[bool]|None): Determine the sampling times Ti to use. If None, all will be used. poly_deg (int): The degree of the polynomial to fit. For monoexponential fits, use num=1. full (bool): Calculate additional information on the fit performance. If True, more information is given. If False, only the optimized parameters are returned. time_units (str|float|int): Units of measurement of Ti. If str, any valid SI time unit (e.g. `ms`, `ns`) will be accepted. If int or float, the conversion factor will be multiplied to `ti`. Returns: results (OrderedDict): The multiple components of the polynomial fit. The following terms are present: - `s0` (np.ndarray): The constant term. - `dphs_{i}` (np.ndarray): The monomial term(s); `i` is between 1 and `poly_deg` (both included). """ units_factor = 1 if isinstance(time_units, str) and 's' in time_units: prefix, _ = time_units.split('s', 1) units_factor = fc.prefix_to_factor(prefix) elif isinstance(time_units, (int, float)): units_factor = time_units else: warnings.warn(fmtm('Invalid units `{time_units}`. Ignored.')) tis = np.array(fc.auto_repeat(tis, 1)) * units_factor y_arr = np.array(phs_arr).astype(float) x_arr = np.array(tis).astype(float) if tis_mask is not None: y_arr = y_arr[..., tis_mask] x_arr = x_arr[tis_mask] assert (x_arr.size == y_arr.shape[-1]) p_arr = generic.voxel_curve_fit(y_arr, x_arr, fit_params=1 + poly_deg, method='poly') p_arrs = np.split(p_arr, poly_deg + 1, -1) results = collections.OrderedDict( ('s0' if i == 0 else 'dphs_{i}'.format(i=i), x) for i, x in enumerate(p_arrs[::-1])) if full: raise NotImplementedError return results
def handle_arg(): """ Handle command-line application arguments. """ # :: Create Argument Parser arg_parser = argparse.ArgumentParser( description=__doc__, epilog=fmtm('v.{version} - {author}\n{license}', INFO), formatter_class=argparse.RawDescriptionHelpFormatter) # :: Add POSIX standard arguments arg_parser.add_argument( '--ver', '--version', version=fmt( '%(prog)s - ver. {version}\n{}\n{copyright} {author}\n{notice}', next(line for line in __doc__.splitlines() if line), **INFO), action='version') arg_parser.add_argument( '-v', '--verbose', action='count', default=D_VERB_LVL, help='increase the level of verbosity [%(default)s]') arg_parser.add_argument( '-q', '--quiet', action='store_true', help='override verbosity settings to suppress output [%(default)s]') # :: Add additional arguments arg_parser.add_argument('-f', '--force', action='store_true', help='force new processing [%(default)s]') arg_parser.add_argument('-i', '--input', metavar='FILE', default=None, required=True, help='set input filepath [%(default)s]') arg_parser.add_argument('-o', '--output', metavar='FILE', default=None, help='set output filepath [%(default)s]') arg_parser.add_argument( '-s', '--smoothing', metavar='SIGMA', type=float, default=0.0, help='value of Gaussian smoothing\'s sigma [%(default)s]') arg_parser.add_argument('-a', '--threshold', metavar='METHOD|X', default='otsu', help='thresholding method or value [%(default)s]') arg_parser.add_argument('-A', '--threshold_opts', metavar='JSON', default='{"bins":"sqrt"}', help='comparison directive [%(default)s]') arg_parser.add_argument('-c', '--comparison', metavar='">"|">="|"<"|"<="|"="|"!="', default='>', help='comparison directive [%(default)s]') arg_parser.add_argument( '-e', '--erosion_iter', metavar='N', type=int, default=0, help='number of postprocess binary erosion iterations [%(default)s]') arg_parser.add_argument( '-d', '--dilation_iter', metavar='N', type=int, default=0, help='number of postprocess binary dilation iterations [%(default)s]') arg_parser.add_argument('-t', '--dtype', metavar='TYPE', default='int', help='data type of the output [%(default)s]') return arg_parser