Skip to main content

PyToM-3D: Python Topography Manipulator in 3D

Project description

PyToM-3D: Python Topography Manipulator in 3D

PyToM-3D is a Python package to transform and fit 3-dimensional topographies. It provides methods to perform traditional geometric transformations and visualise the results as well.

Geometric Transformations

Singular Value Decomposition (SVD)

Data Regression

Data Inspection

Initialising a Topography

Initially, we need to istantiate a Topography:

t = Topography()

We have a multitude of options:

  • reading from a .csv file;

  • generating a grid and add synthetic data.

Geometric Transformations

In order to understand each geometric transformation remember that the points of the topography are stored in the attribute P, which is a $N\times 3$ matrix:

$$\mathbf{P} = \begin{bmatrix} x_1 & y_1 & z_1 \\ x_2 & y_2 & z_2 \\ \vdots & \vdots & \vdots \\ x_N & y_N & z_N\end{bmatrix},$$

where $\mathbf{p}_i = \left[x_i\quad y_i \quad z_i\right]$ is the ith point of the topography. In practice the altitude $z_i$ is determined upon a latent function of the coordinates, hence $z_i = f(x_i, y_i)$.

Translation

Let us define a vector $\mathbf{v} = \left[x_v\quad y_v\quad z_v \right]$. By calling:

t.translate([xv,yv,zv])

we translate $\mathbf{P}$ by $\mathbf{v}$ as:

$$\mathbf{p}_i \leftarrow \mathbf{p}_i + \mathbf{v}\quad\forall\ i = 1,2,\dots,N.$$

Rotation

This method performs the rotation about the centre given three rotation angles $\theta_x$, $\theta_y$, $\theta_z$. The method builds the corresponding rotation matrices:

$$\mathbf{R}_x = \begin{bmatrix} 1 & 0 & 0 \\ 0 & \cos(\theta_x) & \sin(\theta_x) \\ 0 & -\sin(\theta_x) & \cos(\theta_x) \\ \end{bmatrix},$$

$$\mathbf{R}_y = \begin{bmatrix} \cos(\theta_y) & 0 & \sin(\theta_y) \\ 0 & 1 & 0 \\ -\sin(\theta_y) & 0 & \cos(\theta_y) \end{bmatrix},$$

$$\mathbf{R}_z = \begin{bmatrix} \cos(\theta_z) & \sin(\theta_z) & 0 \\ -\sin(\theta_z) & \cos(\theta_z) & 0 \\ 0 & 0 & 1 \end{bmatrix},$$

$$\mathbf{R} = \mathbf{R}_x\mathbf{R}_y\mathbf{R}_z.$$

Then each point is rotated as:

$$\mathbf{p}_i \leftarrow \mathbf{R}\mathbf{p}_i.$$

This is accomplished via:

t.rotate(t_deg=[t_x, t_y, t_z])

The method supports passing a rotation matrix too:

t.rotate(rot_mat=R)

In case on wishes to rotate about a given centre $c=\left[c_x\quad c_y\quad c_z\right]^\top$, they would call the wrapper method:

t.rotate_about_centre(c=[c_x, c_y, c_z]t_deg=[t_x, t_y, t_z])

or by providing a rotation matrix rot_mat.

Flip

This method allows mirroring data with respect to a given vector $\mathbf{v}=\left[v_x\quad v_y\quad v_z \right]$ which represent the outward normal of the intended flipping plane. Assuming one wishes to flip the data about the $yz$ plane, they would define $\mathbf{v}=\left[-1\quad 1\quad 1 \right]$, and call:

t.flip([-1,1,1])

This operation performs $(\mathbf{p}_i = \left[x_i\quad y_i \quad z_i\right])$:

$$\left[x_i\quad y_i \quad z_i\right] \leftarrow \left[x_i\cdot v_x\quad y_i\cdot vy\quad z_i\cdot vz\right] \quad\forall\ i = 1,2,\dots,N.$$

Cut

Suppose you would like to remove some outliers from topography. Although the same procedure applies to the other axes identically, we focus on the z-axis. We also assume two threshold $l$ and $u$, whereby we filter each $i$th datum using the criterion:

$$z_i \leftarrow z_i:\quad z_i > l\quad \text{and}\quad z_i < u.$$

To do so, we call:

t.cut(ax="z", lo=l, up=u, out=False)

If out=True the method keep the points complying with:

$$z_i \leftarrow z_i:\quad z_i < l\quad \text{and}\quad z_i > u.$$

Singular Value Decomposition (SVD)

Introduction

Let $\mathbf{P}$ be a generic matrix belonging to $\mathbb{R}^{m\times n}$. SVD allows $\mathbf{P}$ to be decomposed into the product of three matrices:

$$\mathbf{P} = \mathbf{U}\mathbf{S}\mathbf{V^\top},$$

where $\mathbf{U}\in \mathbb{R}^{m\times m}$ , and $\mathbf{V}^\top\in \mathbb{R}^{n\times n}$ are called respectively left- and right-principal matrix (both orthonormal), whereas $\mathbf{S}\in \mathbb{R}^{m\times n}$ is the so-called Singular Value Matrix.

We do SVD via:

t.svd()

Using SVD

Suppose that the points of the topography are distributed according to three preferred directions, which are identifiable by visual inspection. Assume that these directions define a reference frame $\{x_s,y_s,z_s\}$. Conversely, assume that the points forming the point topography have been acquired with respect to another (arbitrary) reference frame $\{x,y,z\}$, which (unfortunately) is not aligned with $\{x_s,y_s,z_s\}$. However, expressing the acquired points with respect to $\{x_s,y_s,z_s\}$ would be of considerable interest, e.g. for further numerical computations. From a mathematical standpoint, a change of reference frame, i.e. change of basis, from $\{x,y,z\}$ to $\{x_s,y_s,z_s\}$ is sought as well as the associated matrix.

In this instance, it is therefore evident that finding this matrix by inspection, intuition or 'trial & error' becomes preposterous. SVD holds the potential to compute such a matrix almost automatically. Let $\mathbf{P}\in\mathbb{R}^{N\times 3}$ be the matrix representing the topography. In order to apply the SVD and obtain satisfactory results, the whole point topography should be translated to $-G$ (the centroid). Following, the SVD applied to $\mathbf{P}$ provides $\mathbf{U}\in \mathbb{R}^{N\times N}$ , $\mathbf{S}\in \mathbb{R}^{N\times 3}$, and $\mathbf{V}^\top\in \mathbb{R}^{3\times 3}$. In particular, $\mathbf{V}$ realises the change of basis. Hence, each point of $\mathbf{P}$, namely $\mathbf{p}_i$, will be rotated according to $\mathbf{V}^\top$:

$$\mathbf{p}_i \leftarrow \mathbf{V}^\top\mathbf{p}_i.$$

To perform this, just invoke:

t.rotate_by_svd()

which wraps rotate_about_centre.

Since $\mathbf{V}^\top$ is orthonormal, the topography is subjected to a rigid rotation: neither stretching nor deformations occur. If the $\det{V^\top} \simeq -1$, the transformed topography (through SVD) may need flipping. To overcome this, just use flip (Flip).

Data Regression

Gaussian Process Regression (GPR)

PyToM-3D wraps the regressors of scikit-learn, amongst which GPR. In this instance, the topography is modelled as the following regression model:

$$t(x,y) = f(x,y) + \epsilon(0, \sigma),$$

where $f(x,y)$ is a latent function modelling the topography and $\epsilon$ is Gaussian noise having null mean and $\sigma$ as the standard deviation. Next, a Gaussian Process is placed over $f(x,y)$:

$$f \sim GP(M(x,y), K(x,y)),$$

where $M(x,y)$ is the mean, and $K(x,y)$ is the kernel (covariance function). Initially, we need to define the kernel:

from sklearn.gaussian_process.kernels import RBF, WhiteKernel, ConstantKernel
kernel = ConstantKernel() * RBF([1.0, 1.0], (1e-5, 1e5)) \
                + WhiteKernel(noise_level=1e-3, noise_level_bounds=(1e-5, 1e5))

which represents a typical squared exponential kernel with noise:

$$K(\mathbf{x},\mathbf{x}') = C \exp{\left(\frac{\Vert \mathbf{x} - \mathbf{x}'\Vert^2}{l^2}\right)} + \sigma_{ij},$$

where:

$$\sigma_{ij} = \delta_{ij} \epsilon,\quad \mathbf{x}=\left[x,y\right]$$

and $\delta_{ij}$ is Kronecker's delta applied to any pair of points $\mathbf{x}_{i}$, $\mathbf{x}_j$.

Finally, we invoke:

from sklearn.gaussian_process import GaussianProcessRegressor as gpr
t.fit(gpr(kernel=kernel))

and the GPR is fit. To predict data:

t.pred(X)

where X is $M \times 2$ a numpy array containing the $x$ and $y$ coordinates of an evaluation grid.

Spline Fitting

PyToM-3D allows user to fit data by bi-variate splines specifically wrapping scipy.interpolate.bisplrep. Modelling the topography as a two-variable function $f(x,y)$, we approximate it as:

$$f(x,y) \approx \sum_{i=1}^{m} \sum_{j=1}^{n} C_{ij} Q_{i,r}(x) Q_{j,s}(y), $$

where $Q_{i,r}$ and $Q_{j,s}$ are polynomials of degree $r$ and $s$ respectively. Additionally, $m$ and $n$ are the number of control points (aka knots) distributed along the $x$- and $y$-axis. Lastly, $C_{ij}$ are the trainable coefficients, which are determined upon the points of the topography.

To fit a bi-variate spline to the data, we call:

from scipy.interpolate import bisplrep
t.fit(bisplrep, kx, ky, tx, ty)

where kx, ky represent the above-mentioned $r$ and $s$ (degree of the polynomials), and tx and ty are the control points, which are expected to be np.ndarray-like objects. Once the fitting is done we forecast the topography elsewhere by:

t.pred(X)

Data Inspection

PyToM-3D offers afew visualisation utilities to inspect the data. Particularly, it exploits pytom3d.Viewer.Viewer class. So we need one istance of this class before proceeding:

from pytom3d.Viewer import Viewer
v = Viewer()

2D Views

We can easily display the three Cartesian views of the topography t, by using:

v.views2D(t)

The method can take an indefinite number of input topographies.

3D Scatter

Similarly we can easily the 3D scatter plot of t with:

v.scatter(t)

The method accepts an indefinite number of input topographies.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytom3d-0.0.0rc0.tar.gz (33.3 kB view details)

Uploaded Source

Built Distribution

pytom3d-0.0.0rc0-py3-none-any.whl (31.1 kB view details)

Uploaded Python 3

File details

Details for the file pytom3d-0.0.0rc0.tar.gz.

File metadata

  • Download URL: pytom3d-0.0.0rc0.tar.gz
  • Upload date:
  • Size: 33.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.8.10

File hashes

Hashes for pytom3d-0.0.0rc0.tar.gz
Algorithm Hash digest
SHA256 edfab32cdb1e7a45b18fb2f58f37f0e8e6fec487f4af90e344da1988ce2e04d0
MD5 8d74a83cf0791b74cfbd318cf6e073d2
BLAKE2b-256 5450ae5e087c3cd3700216aea3e28d649f195b383ab770df73bfc276ad9e622b

See more details on using hashes here.

File details

Details for the file pytom3d-0.0.0rc0-py3-none-any.whl.

File metadata

  • Download URL: pytom3d-0.0.0rc0-py3-none-any.whl
  • Upload date:
  • Size: 31.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.8.10

File hashes

Hashes for pytom3d-0.0.0rc0-py3-none-any.whl
Algorithm Hash digest
SHA256 1092be54e7fdd2e03ee601ac157dd1b9bb6e8065031b325144ed7c0f80ac44c2
MD5 bb0c6047c725d2f8613cd10125e171bb
BLAKE2b-256 5e37645e9de4c17b6e6b79a026b98beff21afed4990171b7a1ab114b0dc2d4ca

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page