orbital_tomog_3d_data_processor.py 3.75 KB
Newer Older
1
2
3
from .orbitaltomog_data_processor import support_from_autocorrelation
from proxtoolbox.Utilities.OrbitalTomog.array_tools import shifted_fft, shifted_ifft
from proxtoolbox.Utilities.OrbitalTomog.binning import bin_2d_array, bin_array
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
from skimage.io import imread
from .Graphics.stack_viewer import XYZStackViewer


def data_processor(config):
    inp = imread(config['data_filename'])
    ny, nx, nz = inp.shape
    config['data'] = abs(inp)

    # Keep the same resolution? TODO: streamline for 3D arpes data with many unknown values (NaNs) in the data set
Matthijs's avatar
Matthijs committed
15
16
    if 'Ny' not in config or 'Nx' not in config or 'Nz' not in config:
        print('Setting problem dimensions based on data')
17
        config['Ny'], config['Nx'], config['Nz'] = ny, nx, nz
Matthijs's avatar
Matthijs committed
18
19
    elif (ny != config['Ny'] or nz != config['Nx'] or nz != config['Nz']) \
            and ny % config['Ny'] == 0 and nx % config["Nx"] == 0 and nz % config['Nz'] == 0:
20
21
22
23
24
25
26
27
        # binning must be done for the intensity-data, as that preserves the normalization
        if not ('from intensity data' in config and config['from intensity data']):
            config['data'] = np.sqrt(bin_array(config['data'] ** 2, (config['Ny'], config["Nx"], config['Nz'])))
        else:
            config['data'] = bin_2d_array(config['data'], (config['Ny'], config["Nx"]))
    else:
        raise ValueError('Incompatible values for Ny, Nx, Nz given in configuration dict')

Matthijs's avatar
Matthijs committed
28
29
30
31
32
    # Load measurement sensitivity, determine data_zeros
    sensitivity = imread(config['sensitivity_filename'])
    config['data_zeros'] = sensitivity == 0
    assert config['data_zeros'].shape == config['data'].shape, 'Non-matching sensitivity and data arrays'

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
    # Calculate electric field
    if 'from intensity data' in config and config['from intensity data']:
        # avoid sqrt of negative numbers (due to background subtraction)
        config['data'] = np.where(config['data'] > 0,
                                  np.sqrt(abs(config['data'])),
                                  np.zeros_like(config['data']))
    config['norm_data'] = np.sqrt(np.sum(config['data'] ** 2))

    # Object support determination
    try:
        config['support'] = imread(config['support_filename'])
    except KeyError:  # 'support filename does not exist, so define a support here'
        if 'threshold for support' not in config:
            config['threshold for support'] = 0.1
        config['support'] = support_from_autocorrelation(config['data'],
                                                         threshold=config['threshold for support'],
                                                         absolute_autocorrelation=True,
                                                         binary_dilate_support=1)

    if ('use_sparsity_with_support' in config
            and config['use_sparsity_with_support']
            and 'sparsity_support' not in config):
        if 'threshold for support' not in config:
            config['threshold for support'] = 0.1
        config['sparsity_support'] = support_from_autocorrelation(config['data'],
                                                                  threshold=config['threshold for support'],
                                                                  binary_dilate_support=1)

    # Initial guess
Matthijs's avatar
Matthijs committed
62
    ph_init = 2 * np.pi * np.random.random_sample(inp.shape)
63
64
65
66
67
    config['u_0'] = inp * np.exp(1j * ph_init)

    if config['dataprocessor_plotting']:
        XYZStackViewer(inp, cmap='viridis')
        XYZStackViewer(shifted_fft(inp).real)
68
        # TODO: investigate why these viewers crash after a limited time
69
70
71
72
73
74
75
76
77

    # Other settings
    config['fresnel_nr'] = 0
    config['FT_conv_kernel'] = 1
    config['use_farfield_formula'] = True
    config['magn'] = 1
    config['data_sq'] = abs(config['data']) ** 2

    return config