Source code for abel.tools.basis

# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

import os.path
import numpy as np
import abel

[docs]def get_bs_cached(method, cols, basis_dir='.', basis_options=dict(), verbose=False): """load basis set from disk, generate and store if not available. Checks whether file ``{method}_basis_{cols}_{cols}*.npy`` is present in `basis_dir` (*) special case for ``linbasex`` _{legendre_orders}_{proj_angles}_{radial_step}_{clip} where {legendre_orders} = str of the list elements, typically '02' (proj_angles} = str of the list elements, typically '04590135' {radial_step} = pixel grid size, usually 1 {clip} = clipping size, usually 0 Either, read basis array or generate basis, saving it to the file. Parameters ---------- method : str Abel transform method, currently ``linbasex``, ``onion_peeling``, ``three_point``, and ``two_point`` cols : int width of image basis_dir : str path to the directory for saving / loading the basis verbose: boolean print information for debugging Returns ------- D: numpy 2D array of shape (cols, cols) basis operator array file.npy: file saves basis to file name ``{method}_basis_{cols}_{cols}*.npy`` * == ``__{legendre_orders}_{proj_angles}_{radial_step}_{clip}`` for ``linbasex`` method """ basis_generator = { "linbasex": abel.linbasex._bs_linbasex, "onion_peeling": abel.dasch._bs_onion_peeling, "three_point": abel.dasch._bs_three_point, "two_point": abel.dasch._bs_two_point } if method not in basis_generator.keys(): raise ValueError("basis generating function for method '{}' not know" .format(method)) basis_name = "{}_basis_{}_{}".format(method, cols, cols) # special case linbasex requires additional identifying parameters # # linbasex_basis_cols_cols_02_090_0.npy if method == "linbasex": # Fix Me! not a simple unique naming mechanism for key in ['legendre_orders', 'proj_angles', 'radial_step', 'clip']: if key in basis_options.keys(): if key == 'legendre_orders': value = ''.join(map(str, basis_options[key])) elif key == 'proj_angles': # in radians, convert to % of pi proj_angles_fractpi =\ np.array(basis_options['proj_angles'])*100/np.pi value = ''.join(map(str, proj_angles_fractpi.astype(int))) else: value = basis_options[key] else: # missing option, use defaults default = {'legendre_orders':'02', 'proj_angles':'050', 'radial_step':1, 'clip':0} value = default[key] basis_name += "_{}".format(value) basis_name += ".npy" D = None if basis_dir is not None: path_to_basis_file = os.path.join(basis_dir, basis_name) if os.path.exists(path_to_basis_file): if verbose: print("Loading {} operator matrix...", method) try: D = np.load(path_to_basis_file) return D except ValueError: raise except: raise if verbose: print("A suitable operator matrix for '{}' was not found.\n" .format(method), "A new operator matrix will be generated.") if basis_dir is not None: print("But don\'t worry, it will be saved to disk for future", " use.\n") else: pass D = basis_generator[method](cols, **basis_options) if basis_dir is not None: np.save(path_to_basis_file, D) if verbose: print("Operator matrix saved for later use to,") print(' '*10 + '{}'.format(path_to_basis_file)) return D