def test_transform_ie_simple(self):
        """Class SpharaTransform, mode='inv_euclidean', simple triangular mesh

        Determine the SPHARA forward and inverse transform with
        inverse Euclidean edge weight for a simple triangular mesh, 3
        vertices, single triangle.

        """
        # define the simple test mesh
        testtrimesh = tm.TriMesh([[0, 1, 2]],
                                 [[1, 0, 0], [0, 2, 0], [0, 0, 3]])

        # create a SPHARA transform instance for the mesh
        st_ie_simple = st.SpharaTransform(testtrimesh, mode='inv_euclidean')

        # the data to transform
        data = np.concatenate([[[0., 0., 0.], [1., 1., 1.]],
                               np.transpose(st_ie_simple.basis()[0])])

        # SPHARA analysis
        coef_ie_simple = st_ie_simple.analysis(data)

        # SPHARA synthesis
        recon_ie_simple = st_ie_simple.synthesis(coef_ie_simple)

        self.assertTrue(
            np.allclose(np.absolute(coef_ie_simple),
                        [[0.0, 0.0, 0.0], [1.73205081, 0.0, 0.0],
                         [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]])
            and np.allclose(recon_ie_simple, data))
Exemple #2
0
    def test_filter_fem_allpass_simple(self):
        """Class SpharaFilter, mode='fem', allpass, simple mesh

        Apply a SPHARA spatial allpass filter with fem edge weight to
        data sampled at a simple triangular mesh, 3 vertices, single
        triangle.

        """
        # define the simple test mesh
        testtrimesh = tm.TriMesh([[0, 1, 2]],
                                 [[1, 0, 0], [0, 2, 0], [0, 0, 3]])

        # create a SPHARA filter instance for the mesh
        sf_fem_simple = sf.SpharaFilter(testtrimesh,
                                        mode='fem',
                                        specification=0)

        # the data to filter
        data = np.concatenate([[[0., 0., 0.], [1., 1., 1.]],
                               np.transpose(sf_fem_simple.basis()[0])])

        # apply SPHARA based spatial allpass filter
        data_filt_fem_simple = sf_fem_simple.filter(data)

        self.assertTrue(np.allclose(data_filt_fem_simple, data))
Exemple #3
0
    def test_filter_unit_dc_simple(self):
        """Class SpharaFilter, mode='unit', dc-pass, simple mesh

        Apply a SPHARA spatial dc-pass filter with unit edge weight to
        data sampled at a simple triangular mesh, 3 vertices, single
        triangle.

        """
        # define the simple test mesh
        testtrimesh = tm.TriMesh([[0, 1, 2]],
                                 [[1, 0, 0], [0, 2, 0], [0, 0, 3]])

        # create a SPHARA filter instance for the mesh
        sf_unit_simple = sf.SpharaFilter(testtrimesh,
                                         mode='unit',
                                         specification=1)

        # the data to filter
        data = np.concatenate([[[0., 0., 0.], [1., 1., 1.]],
                               np.transpose(sf_unit_simple.basis()[0])])

        # reference for filtered data
        data_filt_ref = data.copy()
        data_filt_ref[3] = [0., 0., 0.]
        data_filt_ref[4] = [0., 0., 0.]

        # apply SPHARA based spatial dc-pass filter
        data_filt_unit_simple = sf_unit_simple.filter(data)

        self.assertTrue(np.allclose(data_filt_unit_simple, data_filt_ref))
Exemple #4
0
    def test_basis_fem_result(self):
        """Class SpharaBasis, method basis, mode='fem', triangular test mesh

        Determine the SPHARA basis with FEM discretization for a
        triangular mesh with 118 vertices. The valid basis vectors of
        the SPHARA basis can point in opposite directions
        (multiplication by -1). To compare the calculated basis with
        the reference basis, the transposed matrix of the calculated
        basis is multiplied by the matrix of the reference basis. If
        the calculated basis is correct, then the result matrix of the
        matrix multiplication contains only the elements 1 and -1 at
        the main diagonal, all other elements of the matrix are 0 or
        very small.

        """
        testtrimesh = tm.TriMesh(self.testdatatriangles, self.testdatavertices)
        sb_fem = sb.SpharaBasis(testtrimesh, mode='fem')
        sb_fem_fun, sb_fem_freq = sb_fem.basis()
        self.assertTrue(
            np.allclose(
                np.absolute(
                    np.matmul(
                        np.matmul(np.transpose(sb_fem_fun),
                                  self.testdatamassmatrix),
                        self.testdataspharabasisfemweight)),
                np.identity(np.size(sb_fem_freq)))
            and np.allclose(sb_fem_freq, self.testdataspharanatfreqfemweight))
    def test_massmatrix_result(self):
        """
        Class TriMesh, method massmatrix, triangular test mesh

        Determine the mass matrix for a triangular mesh with 118 vertices.
        """
        testtrimesh = tm.TriMesh(self.testdatatriangles, self.testdatavertices)
        (self.assertTrue(
            np.allclose(testtrimesh.massmatrix(), self.testdatamassmatrix)))
    def test_tri_mesh_constructor_dimension(self):
        """
        Class TriMesh, constructor, dimension exception

        Raise an exception if triangle list has wrong dimension.
        """
        with self.assertRaises(ValueError) as cm:
            tm.TriMesh([1, 2, 3, 4], [1, 2, 3, 4])
        err = cm.exception
        self.assertEqual(str(err), 'Triangle list has to be 2D!')
    def test_weightmatrix_unitweight_result(self):
        """
        Class TriMesh, method weightmatrix, mode='unit', triangular test mesh

        Determine the weight matrix with unit edge weight for a triangular mesh
        with 118 vertices.
        """
        testtrimesh = tm.TriMesh(self.testdatatriangles, self.testdatavertices)
        self.assertTrue(
            np.array_equal(testtrimesh.weightmatrix(mode='unit'),
                           self.testdataweightmatrixunitweight))
    def test_laplacianmatrix_halfcot_result(self):
        """
        Class TriMesh, method laplacianmatrix, mode='half_cotangent',
        triangular test mesh

        Determine the laplacian matrix (half cotangent edge weighting) for
        a triangular mesh with 118 vertices.
        """
        testtrimesh = tm.TriMesh(self.testdatatriangles, self.testdatavertices)
        (self.assertTrue(
            np.allclose(testtrimesh.laplacianmatrix(mode='half_cotangent'),
                        self.testdatalaplacianmatrixhalfcotweight)))
    def test_weightmatrix_unitweight_simple(self):
        """
        Class TriMesh, method weightmatrix, mode='unit', simple triangular mesh

        Determine the weight matrix with unit edge weight for a simple
        triangular mesh, 3 vertices, single triangle, equilateral.
        """
        testtrimesh = tm.TriMesh([[0, 1, 2]],
                                 [[1., 0., 0.], [0., 2., 0.], [0., 0., 3.]])
        self.assertTrue(
            np.allclose(testtrimesh.weightmatrix(mode='unit'),
                        [[0.0, 1.0, 1.0], [1.0, 0.0, 1.0], [1.0, 1.0, 0.0]]))
    def test_laplacianmatrix_inveuclid_result(self):
        """
        Class TriMesh, method laplacianmatrix, mode='inv_euclidean', triangular
        test mesh

        Determine the laplacian matrix (inverse euclidean edge weighting) for
        a triangular mesh with 118 vertices.
        """
        testtrimesh = tm.TriMesh(self.testdatatriangles, self.testdatavertices)
        (self.assertTrue(
            np.allclose(testtrimesh.laplacianmatrix(mode='inv_euclidean'),
                        self.testdatalaplacianmatrixieweight)))
    def test_massmatrix_simple(self):
        """Class TriMesh, method massmatrix, simple triangular mesh

        Determine the mass matrix for a simple triangular mesh, 3
        vertices, single triangle, equilateral.
        """
        testtrimesh = tm.TriMesh([[0, 1, 2]],
                                 [[1., 0., 0.], [0., 2., 0.], [0., 0., 3.]])
        self.assertTrue(
            np.allclose(testtrimesh.massmatrix(),
                        [[0.58333333, 0.29166667, 0.29166667],
                         [0.29166667, 0.58333333, 0.29166667],
                         [0.29166667, 0.29166667, 0.58333333]]))
    def test_tri_mesh_constructor_three_row(self):
        """
        Class TriMesh, constructor, non 3 elem exception

        Raise an exception if the rows of the triangle list dont consists of
        3 integers.
        """
        with self.assertRaises(ValueError) as cm:
            tm.TriMesh([[0, 1], [2, 3]], [[1, 2], [3, 4]])
        err = cm.exception
        self.assertEqual(
            str(err), 'Each entry of the triangle list has to '
            'consist of three elements!')
    def test_stiffnessmatrix_simple(self):
        """Class TriMesh, method stiffnessmatrix, simple triangular mesh

        Determine the stiffness matrix for a simple triangular mesh, 3
        vertices, single triangle, equilateral.
        """
        testtrimesh = tm.TriMesh([[0, 1, 2]],
                                 [[1., 0., 0.], [0., 2., 0.], [0., 0., 3.]])
        self.assertTrue(
            np.allclose(testtrimesh.stiffnessmatrix(),
                        [[-0.92857143, 0.64285714, 0.28571429],
                         [0.64285714, -0.71428571, 0.07142857],
                         [0.28571429, 0.07142857, -0.35714286]]))
    def test_laplacianmatrix_unit_simple(self):
        """
        Class TriMesh, method laplacianmatrix, mode='unit', simple triangular
        mesh

        Determine the laplacian matrix (unit edge weighting) for a simple
        triangular mesh, 3 vertices, single triangle, equilateral.
        """
        testtrimesh = tm.TriMesh([[0, 1, 2]],
                                 [[1., 0., 0.], [0., 2., 0.], [0., 0., 3.]])
        self.assertTrue(
            np.allclose(testtrimesh.laplacianmatrix(mode='unit'),
                        [[2, -1, -1], [-1, 2, -1], [-1, -1, 2]]))
    def test_weightmatrix_inveuclid_simple(self):
        """
        Class TriMesh, method weightmatrix, mode='inv_euclidean', simple
        triangular mesh

        Determine the weight matrix with inverse euclidean edge weight for a
        simple triangular mesh, 3 vertices, single triangle, equilateral.
        """
        testtrimesh = tm.TriMesh([[0, 1, 2]],
                                 [[1., 0., 0.], [0., 2., 0.], [0., 0., 3.]])
        self.assertTrue(
            np.allclose(
                testtrimesh.weightmatrix(mode='inv_euclidean'),
                [[0., 0.4472136, 0.31622777], [0.4472136, 0., 0.2773501],
                 [0.31622777, 0.2773501, 0.]]))
    def test_weightmatrix_halfcot_simple(self):
        """
        Class TriMesh, method weightmatrix, mode='half_cotangent', simple
        triangular mesh

        Determine the weight matrix with unit edge weight for a simple
        triangular mesh, 3 vertices, single triangle, equilateral.
        """
        testtrimesh = tm.TriMesh([[0, 1, 2]],
                                 [[1., 0., 0.], [0., 2., 0.], [0., 0., 3.]])
        self.assertTrue(
            np.allclose(
                testtrimesh.weightmatrix(mode='half_cotangent'),
                [[0., 0.64285714, 0.28571429], [0.64285714, 0., 0.07142857],
                 [0.28571429, 0.07142857, 0.]]))
    def test_laplacianmatrix_halfcot_simple(self):
        """
        Class TriMesh, method laplacianmatrix, mode='half_cotangent', simple
        triangular mesh

        Determine the laplacian matrix (half cotangent edge weighting) for
        a simple triangular mesh, 3 vertices, single triangle, equilateral.
        """
        testtrimesh = tm.TriMesh([[0, 1, 2]],
                                 [[1., 0., 0.], [0., 2., 0.], [0., 0., 3.]])
        (self.assertTrue(
            np.allclose(testtrimesh.laplacianmatrix(mode='half_cotangent'),
                        [[0.92857143, -0.64285714, -0.28571429],
                         [-0.64285714, 0.71428571, -0.07142857],
                         [-0.28571429, -0.07142857, 0.35714286]])))
    def test_laplacianmatrix_inveuclid_simple(self):
        """
        Class TriMesh, method laplacianmatrix, mode='inv_euclidean', simple
        triangular mesh

        Determine the laplacian matrix (inverse euclidean edge weighting) for
        a simple triangular mesh, 3 vertices, single triangle, equilateral.
        """
        testtrimesh = tm.TriMesh([[0, 1, 2]],
                                 [[1., 0., 0.], [0., 2., 0.], [0., 0., 3.]])
        (self.assertTrue(
            np.allclose(testtrimesh.laplacianmatrix(mode='inv_euclidean'),
                        [[0.76344136, -0.4472136, -0.31622777],
                         [-0.4472136, 0.72456369, -0.2773501],
                         [-0.31622777, -0.2773501, 0.59357786]])))
Exemple #19
0
    def test_basis_fem_simple(self):
        """
        Class SpharaBasis, method basis, mode='fem', simple triangular mesh

        Determine the SPHARA basis with fem edge weight
        for a simple triangular mesh, 3 vertices, single triangle.

        """
        testtrimesh = tm.TriMesh([[0, 1, 2]],
                                 [[1., 0., 0.], [0., 2., 0.], [0., 0., 3.]])
        sb_fem = sb.SpharaBasis(testtrimesh, mode='fem')
        sb_fem_fun, sb_fem_freq = sb_fem.basis()
        self.assertTrue(
            np.allclose(sb_fem_fun, [[0.53452248, -0.49487166, 1.42857143],
                                     [0.53452248, -0.98974332, -1.14285714],
                                     [0.53452248, 1.48461498, -0.28571429]])
            and np.allclose(sb_fem_freq,
                            [2.33627569e-16, 1.71428571e+00, 5.14285714e+00]))
Exemple #20
0
    def test_basis_unit_simple(self):
        """
        Class SpharaBasis, method basis, mode='unit', simple triangular mesh

        Determine the SPHARA basis with unit edge weight for a simple
        triangular mesh, 3 vertices, single triangle.
        """
        testtrimesh = tm.TriMesh([[0, 1, 2]],
                                 [[1, 0, 0], [0, 2, 0], [0, 0, 3]])
        sb_unit = sb.SpharaBasis(testtrimesh, mode='unit')
        sb_unit_fun, sb_unit_freq = sb_unit.basis()
        # print(sb_unit_freq.shape)
        self.assertTrue(
            np.allclose(sb_unit_fun, [[0.57735027, 0.81649658, 0.],
                                      [0.57735027, -0.40824829, -0.70710678],
                                      [0.57735027, -0.40824829, 0.70710678]])
            and np.allclose(sb_unit_freq,
                            [2.22044605e-15, 3.00000000e+00, 3.00000000e+00]))
Exemple #21
0
    def test_basis_inveuclid_simple(self):
        """
        Class SpharaBasis, method basis, mode='inv_euclidean', simple
        triangular mesh

        Determine the SPHARA basis with inverse euclidean edge weight
        for a simple triangular mesh, 3 vertices, single triangle.

        """
        testtrimesh = tm.TriMesh([[0, 1, 2]],
                                 [[1, 0, 0], [0, 2, 0], [0, 0, 3]])
        sb_ie = sb.SpharaBasis(testtrimesh, mode='inv_euclidean')
        sb_ie_fun, sb_ie_freq = sb_ie.basis()
        self.assertTrue(
            np.allclose(
                sb_ie_fun,
                [[-0.577350269189626, -0.328082121693334, 0.747682277502862],
                 [-0.577350269189626, -0.483470785430218, -0.657968590665356],
                 [-0.577350269189626, 0.811552907123552, -0.0897136868375066]])
            and np.allclose(sb_ie_freq,
                            [0.0, 0.886644827600501, 1.19493809165832]))
Exemple #22
0
axeeg.set_ylim(-3.5, 3.5)
axeeg.set_xlim(-50, 130)
axeeg.grid(True)
plt.show()
figeeg.savefig('sep_butterfly.pdf')


# ## Create a SpharaPy TriMesh instance

# In the next step we create an instance of the class `spharapy.trimesh.TriMesh` using the list of vertices and triangles.

# In[9]:


# create an instance of the TriMesh class
mesh_eeg = tm.TriMesh(trilist, vertlist)


# ## SPHARA analysis of EEG data

# ### Create a SpharaPy SpharaTransform instance

# Afterwards we determine an instance of the class SpharaTransform, which is used to execute the transformation. For the determination of the SPHARA basis we use a Laplace-Beltrami operator, which is discretized by the FEM approach.

# In[10]:


sphara_transform_fem = st.SpharaTransform(mesh_eeg, 'fem')
basis_functions_fem, natural_frequencies_fem = sphara_transform_fem.basis()

# Determining the Laplace-Beltrami Operator
# -----------------------------------------
#
# In a further step, an instance of the class
# :class:`spharapy.trimesh.TriMesh` is created from the lists of
# vertices and triangles. The class :class:`spharapy.trimesh.TriMesh`
# provides a number of methods to determine certain properties of the
# triangle mesh required to generate the SPHARA basis.

# print all implemented methods of the TriMesh class
print([func for func in dir(tm.TriMesh) if not func.startswith('__')])

######################################################################

# create an instance of the TriMesh class
simple_mesh = tm.TriMesh(trilist, vertlist)

######################################################################
# For the simple triangle mesh an instance of the class SpharaBasis is
# created and the finite element discretization ('fem') is used. The
# complete set of SPHARA basis functions and the natural frequencies
# associated with the basis functions are determined.

sphara_basis = sb.SpharaBasis(simple_mesh, 'fem')
basis_functions, natural_frequencies = sphara_basis.basis()

######################################################################
# The set of SPHARA basis functions can be used for spatial Fourier
# analysis of the spatially irregularly sampled data.
#
# The first 15 spatially low-frequency SPHARA basis functions are