Exemplo n.º 1
0
    def get_kmap(self,
                 E_kin=30,
                 dk=0.03,
                 phi=0,
                 theta=0,
                 psi=0,
                 Ak_type='no',
                 polarization='p',
                 alpha=60,
                 beta=90,
                 gamma=0,
                 symmetrization='no'):
        """Returns a kmap slice from the orbital data.

        Args:
            E_kin (float): Kinetic energy in eV.
            dk (float): Desired k-resolution in kmap in Angstroem^-1.
            phi (float): Euler orientation angle phi in degree.
            theta (float): Euler orientation angle theta in degree.
            psi (float): Euler orientation angle psi in degree.
            Ak_type (string): Treatment of |A.k|^2: either 'no',
                'toroid', 'NanoESCA', 'only-toroid' or 'only-NanoESCA'.
            polarization (string): Either 'p', 's', 'unpolarized', 
                'C+', 'C-' or 'CDAD'.   
            alpha (float): Angle of incidence plane in degree.
            beta (float): Azimuth of incidence plane in degree.
            gamma (float/str): Damping factor for final state in
                Angstroem^-1. str = 'auto' sets gamms automatically
            symmetrization (str): either 'no', '2-fold', '2-fold+mirror',
                '3-fold', '3-fold+mirror','4-fold', '4-fold+mirror'
        Returns:
            (PlotData): PlotData containing the kmap slice.
        """

        # Compute new hemispherical cut if E_kin or dk has changed
        new_cut = self.check_new_cut(E_kin, dk)
        if new_cut: self.set_kinetic_energy(E_kin, dk)

        # Rotate molecule (that is, rotate hemisphere) if angles have changed
        # ... and symmetrize kmap if necessary
        new_orientation = self.check_new_orientation(phi, theta, psi)
        new_symmetrization = self.check_new_symmetrization(symmetrization)
        if new_symmetrization or new_orientation:
            self.set_orientation(phi, theta, psi)
            self.set_symmetry(symmetrization)

        # Compute polarization factor if parameters have changed
        new_Ak = self.check_new_Ak(Ak_type, polarization, alpha, beta, gamma)
        if new_cut or new_Ak:
            self.set_polarization(Ak_type, polarization, alpha, beta, gamma)

        if Ak_type == 'only-toroid' or Ak_type == 'only-NanoESCA':
            return PlotData(self.Ak['data'], self.kmap['krange'])

        else:
            return PlotData(self.Ak['data'] * self.kmap['data'],
                            self.kmap['krange'])
Exemplo n.º 2
0
    def test_incorrect_sub(self):

        data = [[7, 8, 9], [10, 11, 12]]
        range_ = [[1, 3], [-1, 1]]

        second_plot_data = PlotData(data, range_)

        self.assertRaises(ValueError, self.plot_data.__sub__, second_plot_data)
        self.assertRaises(TypeError, self.plot_data.__sub__, 'string')
Exemplo n.º 3
0
    def change_polarization(self,
                            Ak_type='no',
                            polarization='p',
                            alpha=60,
                            beta=90,
                            gamma=0):

        self.set_polarization(Ak_type, polarization, alpha, beta, gamma)
        return PlotData(self.Ak['data'] * self.kmap['data'],
                        self.kmap['krange'])
Exemplo n.º 4
0
    def test_add(self):

        data = [[7, 8, 9], [10, 11, 12]]
        range_ = [[1, 2], [-1, 1]]

        second_plot_data = PlotData(data, range_)

        added_plot_data = self.plot_data + second_plot_data
        npt.assert_equal(added_plot_data.data, [[8, 10, 12], [14, 16, 18]])

        added_plot_data = self.plot_data + 4
        npt.assert_equal(added_plot_data.data, [[5, 6, 7], [8, 9, 10]])
Exemplo n.º 5
0
    def test_correct_initialization(self):

        npt.assert_equal(self.plot_data.data, self.data)
        npt.assert_equal(self.plot_data.range, self.range_)
        npt.assert_equal(self.plot_data.data.shape, (2, 3))
        npt.assert_equal(self.plot_data.x_axis, [1., 1.5, 2.])
        npt.assert_equal(self.plot_data.y_axis, [-1., 1.])
        npt.assert_equal(self.plot_data.step_size, [0.5, 2.])

        self.data = [[1, 2, np.nan], [4, np.inf, 6]]
        plot_data = PlotData(self.data, self.range_)

        npt.assert_equal(plot_data.data, [[1, 2, np.nan], [4, np.nan, 6]])
Exemplo n.º 6
0
    def test_mul(self):

        data = [[2, 2, 2], [3, 3, 3]]
        range_ = [[1, 2], [-1, 1]]

        second_plot_data = PlotData(data, range_)

        mul_plot_data = self.plot_data * second_plot_data
        npt.assert_equal(mul_plot_data.data, [[2, 4, 6], [12, 15, 18]])

        mul_plot_data = second_plot_data * self.plot_data
        npt.assert_equal(mul_plot_data.data, [[2, 4, 6], [12, 15, 18]])

        mul_plot_data = self.plot_data * 4
        npt.assert_equal(mul_plot_data.data, [[4, 8, 12], [16, 20, 24]])
Exemplo n.º 7
0
    def test_sub(self):

        data = [[7, 8, 9], [10, 11, 12]]
        range_ = [[1, 2], [-1, 1]]

        second_plot_data = PlotData(data, range_)

        subed_plot_data = self.plot_data - second_plot_data
        npt.assert_equal(subed_plot_data.data, [[-6, -6, -6], [-6, -6, -6]])

        subed_plot_data = self.plot_data - np.array(data)
        npt.assert_equal(subed_plot_data.data, [[-6, -6, -6], [-6, -6, -6]])

        subed_plot_data = self.plot_data - 4
        npt.assert_equal(subed_plot_data.data, [[-3, -2, -1], [0, 1, 2]])
Exemplo n.º 8
0
    def slice_from_index(self, index, axis=0):
        if axis == 0:
            data = self.data[index, :, :]
            range_ = [self.axes[2].range, self.axes[1].range]

        elif axis == 1:
            data = self.data[:, index, :]
            range_ = [self.axes[2].range, self.axes[0].range]

        elif axis == 2:
            data = self.data[:, :, index]
            range_ = [self.axes[1].range, self.axes[0].range]

        else:
            raise ValueError('axis has to be between 1 and 3')

        return PlotData(data, range_)
Exemplo n.º 9
0
# kMap.py Imports
from kmap.library.plotdata import PlotData
from kmap.model.crosshair_model import CrosshairAnnulusModel

# This script demonstrates the working and functionality for crosshairs
# in kmap on a simple 9x11 grid.

# New Crosshair
x, y, radius, width = 0, 0, 1.5, 1.5
crosshair = CrosshairAnnulusModel(x=x, y=y, radius=radius, width=width)

# Use 7x7 as data from which we cut to better demonstrate working
# The data goes from 0-49 and the pixel center acts is the whole number
global data
data = PlotData(np.reshape(np.array(range(99)), (9, 11)), [[-5, 5], [-4, 4]])
global extent
extent = data.range.flatten() + [-0.5, 0.5, -0.5, 0.5]

export = {}


def plot(axis, x, y, r, w, region, inverted, title=''):
    # Helper Function plotting crosshair and data

    # Set Crosshair
    crosshair.x = x
    crosshair.y = y
    crosshair.radius = r
    crosshair.width = w
Exemplo n.º 10
0
    def setUp(self):

        self.data = [[1, 2, 3], [4, 5, 6]]
        self.range_ = [[1, 2], [-1, 1]]
        self.plot_data = PlotData(self.data, self.range_)
Exemplo n.º 11
0
class TestPlotData(unittest.TestCase):
    def setUp(self):

        self.data = [[1, 2, 3], [4, 5, 6]]
        self.range_ = [[1, 2], [-1, 1]]
        self.plot_data = PlotData(self.data, self.range_)

    def test_correct_initialization(self):

        npt.assert_equal(self.plot_data.data, self.data)
        npt.assert_equal(self.plot_data.range, self.range_)
        npt.assert_equal(self.plot_data.data.shape, (2, 3))
        npt.assert_equal(self.plot_data.x_axis, [1., 1.5, 2.])
        npt.assert_equal(self.plot_data.y_axis, [-1., 1.])
        npt.assert_equal(self.plot_data.step_size, [0.5, 2.])

        self.data = [[1, 2, np.nan], [4, np.inf, 6]]
        plot_data = PlotData(self.data, self.range_)

        npt.assert_equal(plot_data.data, [[1, 2, np.nan], [4, np.nan, 6]])

    def test_incorrect_data_shape(self):

        self.data = [1, 2, 3, 4, 5, 6]
        self.assertRaises(TypeError, PlotData, self.data, self.range_)

    def test_too_small_data(self):

        self.data = [[1], [2]]
        self.assertRaises(TypeError, PlotData, self.data, self.range_)

    def test_incorrect_range_shape(self):

        self.range_ = [[1, 2]]
        self.assertRaises(TypeError, PlotData, self.data, self.range_)

    def test_incorrect_range_values(self):

        self.range_ = [[1, 2], [np.nan, 1]]
        self.assertRaises(ValueError, PlotData, self.data, self.range_)

        self.range_ = [[1, 2], [np.inf, 1]]
        self.assertRaises(ValueError, PlotData, self.data, self.range_)

    def test_basic_interpolation(self):

        new_x_axis = [1.5, 2]
        new_y_axis = [-0.5, 0, 0.5]
        new_data = self.plot_data.interpolate(new_x_axis, new_y_axis)
        npt.assert_equal(new_data.data,
                         [[2.75, 3.75], [3.5, 4.5], [4.25, 5.25]])
        npt.assert_equal(self.plot_data.data, self.data)

        new_x_axis = [-2, 1]
        new_y_axis = [0, -0.5, -10]
        new_data = self.plot_data.interpolate(new_x_axis, new_y_axis)
        npt.assert_equal(new_data.data,
                         [[np.nan, 2.5], [np.nan, 1.75], [np.nan, np.nan]])

        new_x_axis = [1, 1.25, 1.5, 2]
        new_y_axis = [-1, -0.25, 0.5, 1]
        new_data = self.plot_data.interpolate(new_x_axis, new_y_axis)
        npt.assert_equal(new_data.data,
                         [[1., 1.5, 2., 3.], [2.125, 2.625, 3.125, 4.125],
                          [3.25, 3.75, 4.25, 5.25], [4., 4.5, 5., 6.]])

    def test_update_interpolation(self):

        new_x_axis = [1.5, 2]
        new_y_axis = [-0.5, 0, 0.5]
        new_data = self.plot_data.interpolate(new_x_axis,
                                              new_y_axis,
                                              update=True)
        npt.assert_equal(new_data.data,
                         [[2.75, 3.75], [3.5, 4.5], [4.25, 5.25]])
        npt.assert_equal(self.plot_data.data,
                         [[2.75, 3.75], [3.5, 4.5], [4.25, 5.25]])

    def test_increase_range(self):

        new_x_axis = [0, 1, 2, 3]
        new_y_axis = [-1, 0, 1, 2]
        new_data = self.plot_data.interpolate(new_x_axis,
                                              new_y_axis,
                                              update=True)
        npt.assert_equal(
            new_data.data,
            [[np.nan, 1., 3., np.nan], [np.nan, 2.5, 4.5, np.nan],
             [np.nan, 4., 6., np.nan], [np.nan, np.nan, np.nan, np.nan]])
        npt.assert_equal(self.plot_data.x_axis, [0, 1, 2, 3])
        npt.assert_equal(self.plot_data.y_axis, [-1, 0, 1, 2])

    def test_add(self):

        data = [[7, 8, 9], [10, 11, 12]]
        range_ = [[1, 2], [-1, 1]]

        second_plot_data = PlotData(data, range_)

        added_plot_data = self.plot_data + second_plot_data
        npt.assert_equal(added_plot_data.data, [[8, 10, 12], [14, 16, 18]])

        added_plot_data = self.plot_data + 4
        npt.assert_equal(added_plot_data.data, [[5, 6, 7], [8, 9, 10]])

    def test_incorrect_add(self):

        data = [[7, 8, 9], [10, 11, 12]]
        range_ = [[1, 3], [-1, 1]]

        second_plot_data = PlotData(data, range_)

        self.assertRaises(ValueError, self.plot_data.__add__, second_plot_data)
        self.assertRaises(TypeError, self.plot_data.__add__, 'string')

    def test_sub(self):

        data = [[7, 8, 9], [10, 11, 12]]
        range_ = [[1, 2], [-1, 1]]

        second_plot_data = PlotData(data, range_)

        subed_plot_data = self.plot_data - second_plot_data
        npt.assert_equal(subed_plot_data.data, [[-6, -6, -6], [-6, -6, -6]])

        subed_plot_data = self.plot_data - np.array(data)
        npt.assert_equal(subed_plot_data.data, [[-6, -6, -6], [-6, -6, -6]])

        subed_plot_data = self.plot_data - 4
        npt.assert_equal(subed_plot_data.data, [[-3, -2, -1], [0, 1, 2]])

    def test_incorrect_sub(self):

        data = [[7, 8, 9], [10, 11, 12]]
        range_ = [[1, 3], [-1, 1]]

        second_plot_data = PlotData(data, range_)

        self.assertRaises(ValueError, self.plot_data.__sub__, second_plot_data)
        self.assertRaises(TypeError, self.plot_data.__sub__, 'string')

    def test_mul(self):

        data = [[2, 2, 2], [3, 3, 3]]
        range_ = [[1, 2], [-1, 1]]

        second_plot_data = PlotData(data, range_)

        mul_plot_data = self.plot_data * second_plot_data
        npt.assert_equal(mul_plot_data.data, [[2, 4, 6], [12, 15, 18]])

        mul_plot_data = second_plot_data * self.plot_data
        npt.assert_equal(mul_plot_data.data, [[2, 4, 6], [12, 15, 18]])

        mul_plot_data = self.plot_data * 4
        npt.assert_equal(mul_plot_data.data, [[4, 8, 12], [16, 20, 24]])

    def test_incorrect_mul(self):

        data = [[7, 8, 9], [10, 11, 12]]
        range_ = [[1, 3], [-1, 1]]

        second_plot_data = PlotData(data, range_)

        self.assertRaises(ValueError, self.plot_data.__mul__, second_plot_data)
        self.assertRaises(TypeError, self.plot_data.__mul__, 'string')
        self.assertRaises(ValueError, self.plot_data.__rmul__,
                          second_plot_data)
        self.assertRaises(TypeError, self.plot_data.__rmul__, 'string')

    def test_pow(self):

        pow_plot_data = self.plot_data**2
        npt.assert_equal(pow_plot_data.data, [[1, 4, 9], [16, 25, 36]])
Exemplo n.º 12
0
    def set_symmetry(self, symmetrization):
        """Symmterizes the kmap.

        Args:
            symmetrization (str): either 'no', '2-fold', '2-fold+mirror',
                '3-fold', '3-fold+mirror','4-fold', '4-fold+mirror'

        """
        data = PlotData(self.kmap['data'], self.kmap['krange'])

        if symmetrization == '2-fold':
            data.symmetrise(symmetry='2-fold', update=True)

        elif symmetrization == '2-fold+mirror':
            data.symmetrise(symmetry='2-fold', mirror=True, update=True)

        elif symmetrization == '3-fold':
            data.symmetrise(symmetry='3-fold', update=True)

        elif symmetrization == '3-fold+mirror':
            data.symmetrise(symmetry='3-fold', mirror=True, update=True)

        elif symmetrization == '4-fold':
            data.symmetrise(symmetry='4-fold', update=True)

        elif symmetrization == '4-fold+mirror':
            data.symmetrise(symmetry='4-fold', mirror=True, update=True)

        self.kmap['data'] = data.data
        self.kmap['symmetrization'] = symmetrization
Exemplo n.º 13
0
    def matrix_inversion(self):
        """Calling this method will trigger a direct fit via matrix inversion.
        Ax = y --> A^-1y = x

        Returns:
            (list): A list of MinimizerResults. One for each slice
            fitted.
        """

        # Calculate all the orbital maps once for speed
        orbital_kmaps_vector = np.array([
            self._cut_region(self.get_orbital_kmap(orbital.ID,
                                                   self.parameters)).data
            for orbital in self.orbitals
        ])

        # Filter later for non variable parameters
        vary_vector = [
            self.parameters['w_' + str(orbital.ID)].vary
            for orbital in self.orbitals
        ]
        vary_vector.append(self.parameters['c'].vary)

        # Initial values important if orbital or background is not varied
        initials = [
            self.parameters['w_' + str(orbital.ID)].value
            for orbital in self.orbitals
        ]
        initials.append(self.parameters['c'].value)

        weights = []
        for index in self.slice_policy[1]:
            sliced_plot_data = self.get_sliced_kmap(index)
            sliced_kmap = self._cut_region(sliced_plot_data).data
            background = self._get_background(self.parameters)

            # Transform background to a equally sized map
            if not isinstance(background, np.ndarray):
                background *= np.ones(orbital_kmaps_vector[0].shape)
            background[np.isnan(sliced_kmap)] = 0
            background = self._cut_region(
                PlotData(background, sliced_plot_data.range)).data
            aux = np.append(orbital_kmaps_vector, [background], axis=0)

            # All zero background would lead to singular matrix
            if np.all(background == 0):
                vary_vector[-1] = False

            # Subtract orbitals not to be varied from the sliced data once
            for i, (kmap, initial) in enumerate(zip(aux, initials)):
                if not vary_vector[i]:
                    sliced_kmap -= initial * kmap

            N = len(aux)
            A = np.zeros((N, N))
            y = np.zeros(N)
            for i in range(N):
                y[i] = np.nansum(sliced_kmap * aux[i])
                for j in range(N):
                    A[i, j] = np.nansum(aux[i] * aux[j])

            result = np.array(initials)
            try:
                result[vary_vector] = np.linalg.solve(
                    A[np.ix_(vary_vector, vary_vector)], y[vary_vector])

            except np.linalg.LinAlgError as err:
                if 'Singular matrix' in str(err):
                    result = np.zeros(y.shape)
                    print(
                        'WARNING: Slice {index} produced a singular matrix.\nPlease make sure the background is non zero and there aren\'t identical orbitals loaded.'
                    )

                else:
                    raise

            if N == len(orbital_kmaps_vector):
                # == No background
                result = np.append(result, 0)

            weights.append([index, result])

        return self._construct_minimizer_result(weights)