Skip to main content

A python module to analyze surface roughness

Project description


PyPI version DOI Documentation Status

surfalize is a python package for analyzing microscope topography measurement data in terms of surface roughness and other topographic parameters. It is intended primarily for microtextured surfaces and is supposed to replace software packages such as MountainsMap, MultiFileAnalyzer and Gwyddion for the most common tasks.

Disclaimer

The authors make no guarantees for the correctness of any results obtained using this package. The package is an early work in progress and may introduce changes to both implementation details and public API at any point in time. Any results should be validated against established software to verify their correctness, especially when they are intended to be used for scientific publications.

Some parts of the package are more mature and some are in early development stage. Currently, Gaussian filtering and Profile parameters might suffer from some implementation errors and might not be entirely compliant with ISO standards. Care should be taken when relying on these specific functionalities.

How to install

To install the latest release of surfalize, run the following command:

pip install surfalize

If you want to build from source, clone this git repository and run the following command in the root folder of the cloned repository.

pip install .

However, you will need to have both Cython and a C-Compiler installed (MSVC on Windows, gcc on Linux, MinGW is not supported currently). If you install in editable mode using

pip install -e .

be aware that a change of the pyx files does not reinvoke the Cython build process.

Documentation

The documentation is hosted on readthedocs.

Currently supported file formats

Manufacturer Format Reading Writing
Keyence .vk4, .vk6, .vk7 Yes No
Leica .plu Yes No
Sensofar .plu, .plux Yes No
Digital Surf .sur Yes Yes
KLA Zeta .zmg Yes No
Wyko .opd Yes No
Nanofocus .nms Yes No
Alicona .al3d Yes Yes
Digital Surf .sdf Yes No
General .xyz Yes No

Supported roughness parameters

This package aims to implement all parameters defined in ISO 25178. Currently, the following parameters are supported:

Category Parameter Full name Validated against
Height Sa Arithmetic mean height Gwyddion, MountainsMap
Sq Root mean square height Gwyddion, MountainsMap
Sp Maximum peak height Gwyddion, MountainsMap
Sv Maximum valley depth Gwyddion, MountainsMap
Sz Maximum height Gwyddion, MountainsMap
Ssk Skewness Gwyddion, MountainsMap
Sku Kurtosis Gwyddion, MountainsMap
Hybrid Sdr1 Developed interfacial area ratio Gwyddion2, MountainsMap
Sdq Root mean square gradient MountainsMap
Spatial Sal Autocorrelation length -
Str Texture aspect ratio -
Functional Sk Core roughness depth MountainsMap
Spk Reduced peak height MountainsMap
Svk Reduced dale height MountainsMap
Smr1 Material ratio 1 MountainsMap
Smr2 Material ratio 2 MountainsMap
Sxp Peak extreme height MountainsMap
Functional (volume) Vmp Peak material volume MountainsMap
Vmc Core material volume MountainsMap
Vvv Dale void volume MountainsMap
Vvc Core void volume MountainsMap

1 Per default, Sdr calculation uses the algorithm proposed by ISO 25178 and also used by MountainsMap By keyword argument, the Gwyddion algorithm can be used instead.
2 Gwyddion does not support Sdr calculation directly, but calculates surface area and projected area.

Supported parameters of 1d-periodic surfaces

Additionally, this package supports the calculation of non-standard parameters for periodic textured surfaces with one- dimensional periodic structures. The following parameters can be calculated:

Parameter Description
Period Dominant spatial period of the 1d-surface texture
Depth Peak-to-valley depth of the 1d-texture profiles
Aspect ratio Ratio of peak-to-valley depth to spatial period
Homogeneity Homogeneity factor (0 < H < 1) calculated from Gini analysis
Orientation Clockwise angle of the dominant texture to the vertical axis

Supported operations

Operation Description
Leveling Subtraction of least squares fit to a plane
Zeroing Sets the lowest datapoint of the surface to zero
Centering Sets the average value of the surface elevation to zero
Zooming Magnifies the surface by a specified factor
Cropping Crops the surface in a specified rectangle
Rotation Rotates the surface by a specified angle in degrees
Alignment Aligns the surface with the dominant texture direction by rotation
Outlier removal Removes outliers outside n standard deviation from the mean
Thresholding Thresholding based on areal material ratio
Filtering Applies a Gaussian highpass, lowpass or bandpass filter

Basic Usage

from surfalize import Surface

filepath = 'example.vk4'
surface = Surface.load(filepath)
surface.show()

Extracting roughness and topographic parameters

# Individual calculation of parameters
sa = surface.Sa()
sq = surface.Sq()

# Calculation in batch
parameters = surace.roughness_parameters(['Sa', 'Sq', 'Sz'])
>>> parameters
{'Sa': 1.25, 'Sq': 1.47, 'Sz': 2.01} 

# Calculation in batch of all available parameters
all_available_parameters = surace.roughness_parameters()

Performing surface operations

Surface operations return a new Surface object by default. If inplace=True is specified, the operation applies to the Surface object it is called on and returns it to allow for method chaining. Inplace is generally faster since it does not copy the data and does not need to instantiate a new object.

# Levelling the surface using least-sqaures plane compensation

# Returns new Surface object 
surface = surface.level()

# Returns self (to allow for method chaining)
surface.level(inplace=True)

# Filters the surface using a Gaussian filter
surface_low = surface.filter(filter_type='highpass', cutoff=10)

# Filter form and noise
surface_filtered = surface.filter(filter_type='bandpass', cutoff=0.8, cutoff2=10)

# Separate waviness and roughness at a cutoff wavelength of 10 µm and return both
surface_roughness, surface_waviness = surface.filter('both', 10)

# If the surface contains any non-measured points, the points must be interpolated before any other operation can be applied
surface = surface.fill_nonmeasured(method='nearest')

# The surface can be rotated by a specified angle in degrees
# The resulting surface will automatically be cropped to not contain any areas without data
surface = surface.rotate(10)

# Aligning the surface texture to a specified axis by rotation, default is y
surface = surface.align(axis='y')

# Remove outliers
surface = surace.remove_outliers()

# Threshold the surface, default threshold value is 0.5% of the AbbottCurve
surface = surface.threshold(threshold=0.5)
# Non-symmetrical tresholds can be specified
surface = surface.threshold(threshold=(0.2, 0.5))

These methods can be chained:

surface = Surface.load(filepath).level().filter(filter_type='lowpass', cutoff=0.8)
surface.show()

Plotting

The Surface object offers multiple types of plots.

Plotting the topography itself is done using Surface.show(). If the repr of a Surface object is invoked by Jupyter Notebook, it will automaticall call Surface.show().

# Some arguments can be specified 
surface.show(cmap='viridis', maskcolor='red')

The Abbott-Firestone curve and Fourier Transform can be plotted using:

surface.plot_abbott_curve()
# Here we apply a Hanning window to mitigate spectral leakage (recommended) as crop the plotted range of 
# frequencies to fxmax and fymax.
surface.plot_fourier_transform(hanning=True, fxmax=2, fymax=1)

Accessing the raw data

The raw data of a Surface object can be accessed with the attribute data as a two-dimensional numpy array. The pixel resolution in x (horizontal) and y (vertical) is accessed through the attributes step_x and step_y. The width and height in micrometers are accessed through the attributed width_um and height_um. The resolution in pixels is encoded in the named tuple size, holding the dimensions in the form (y, x).

data_2d = surface.data
step_x = surface.step_x
step_y = surface.step_y
ny, nx = surface.size
# or:
nx = surface.size.x
ny = surface.size.y
width = surface.width_um
height = surface.height_um

Batch processing

surfalize provides a module for batch processing and surface roughness evaluation of large sets of measurement files.

from pathlib import Path
from surfalize import Batch

filepaths = Path('folder').glob('*.vk4')

# Create a Batch object that holds the filepaths to the surface files
batch = Batch(filepaths)

Alternatively, the Batch class provides an alternative constructor to initialize the a Batch directly from a folder containing topography files. If the extension argument is not defined, all files corresponding to supported files formats will be loaded. Alternatively, a list of specific formats can also be supplied.

batch = Batch.from_dir('path/to/folder/', extension='.vk4')

All operations of the surface can be applied to the Batch analogously to a Surface object. However, they are not applied immediately but registered for later execution.

batch.level()
batch.filter('highpass', 20)

Each operation on the batch returns the Batch object, allowing for method chaining.

batch = Batch(filepaths).level().filter('highpass', 20).align().center()

The calculation of roughness parameters can be done indiviually and chained.

batch.Sa().Sq().Sq().Sdr()

Arguments to the roughness parameter calculations, such as p and q can be provided in the individual call.

batch.Vmc(p=10, q=80)

Parameters can also be calculated in bulk using Batch.roughness_parameters():

# Computes Sa, Sq, Sz
batch.roughness_parameters(['Sa', 'Sq', 'Sz'])
# Computes all available parameters
batch.roughness_parameters()

If arguments need to be supplied, the parameter must be constructed as a Parameter object:

from surfalize.batch import Parameter
Vmc = Parameter('Vmc', kwargs=dict(p=10, q=80))
batch.roughness_parameters(['Sa', 'Sq', 'Sz', Vmc])

Finally, the batch processing is executed by calling Batch.execute, returning a pd.DataFrame. Optionally, multiprocessing=True can be specified to split the load among all available CPU cores. Moreover, the results can be saved to an Excel Spread sheet by specifiying a path for saveto=r'path\to\excel_file.xlsx.

df = batch.execute(multiprocessing=True)

Optionally, a Batch object can be initialized with a filepath pointing to an Excel File which contains additional parameters, such as laser parameters. The file must contain a column file, which specifies the filename including file extension in the form name.ext, e.g. topography_50X.vk4. All other columns will be merged into the resulting Dataframe that is returned by Batch.execute.

batch = Batch(filespaths, additional_data=r'C:\users\exampleuser\documents\laserparameters.xlsx')
batch.level().filter('highpass', 20).align().roughness_parameters()
df = batch.execute()

Full example: Let's supppose we have four topography files called topo1.vk4, topo2.vk4, topo3.vk4, topo4.vk4 in the folder C:\users\exampleuser\documents\topo_files. Moreover, we have additional information on these files in an Excel files located in C:\users\exampleuser\documents\topo_files\laserparameters.xlsx. The Excel looks like this:

file power pulse_overlap hatch_distance
topo1.vk4 100 20 12.5
topo2.vk4 50 20 12.5
topo3.vk4 100 50 12.5
topo4.vk4 50 50 12.5
from pathlib import Path
from surfalize import Batch

filepaths = Path(r'C:\users\exampleuser\documents\topo_files').glob('*.vk4')
batch = Batch(filespaths, additional_data=r'C:\users\exampleuser\documents\topo_files\laserparameters.xlsx')
batch.level().filter('highpass', 20).align().roughness_parameters(['Sa', 'Sq', 'Sz'])
batch.execute(multiprocessing=True, saveto=r'C:\users\exampleuser\documents\roughness_results.xlsx')

The result will be a DataFrame that looks like this:

file power pulse_overlap hatch_distance Sa Sq Sz
topo1.vk4 100 20 12.5 0.85 1.25 3.10
topo2.vk4 50 20 12.5 0.42 0.51 1.87
topo3.vk4 100 50 12.5 1.34 1.67 3.84
topo4.vk4 50 50 12.5 0.55 0.67 1.99

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

surfalize-0.8.2-cp312-cp312-win_amd64.whl (140.1 kB view details)

Uploaded CPython 3.12 Windows x86-64

surfalize-0.8.2-cp311-cp311-win_amd64.whl (139.7 kB view details)

Uploaded CPython 3.11 Windows x86-64

surfalize-0.8.2-cp310-cp310-win_amd64.whl (139.8 kB view details)

Uploaded CPython 3.10 Windows x86-64

surfalize-0.8.2-cp39-cp39-win_amd64.whl (152.5 kB view details)

Uploaded CPython 3.9 Windows x86-64

File details

Details for the file surfalize-0.8.2-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for surfalize-0.8.2-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 17ac2ad07f5202d40146907d02f778b4137876a89b1ad6be095e206affc726bb
MD5 0eed67b429d2b2cc91a509d9719346c0
BLAKE2b-256 02cdf767e37af4f6f9c1c4c577ec6de1035a5fc719459900330fa5c9e057eacf

See more details on using hashes here.

File details

Details for the file surfalize-0.8.2-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for surfalize-0.8.2-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 46b6529bce836f469bb0ec85fd5eb67994e559434b3cccb45980802458d268a8
MD5 26cc1cc43c281396cde65bdc42207557
BLAKE2b-256 3f1ca8497f024219114870698f1a88100945daf6e3b9737f48cbbc942527f46f

See more details on using hashes here.

File details

Details for the file surfalize-0.8.2-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for surfalize-0.8.2-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 a75ffec489199c4f92ed6fc3d4aed63c02281a0e06c8a9fd9418f7b1ee72ce46
MD5 d2e6b0bfc06028f98e522afcd978b758
BLAKE2b-256 fb797334ebbb96006187d9a8fdca998eec717b0de9a58271bec03df36e4c270f

See more details on using hashes here.

File details

Details for the file surfalize-0.8.2-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: surfalize-0.8.2-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 152.5 kB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.5

File hashes

Hashes for surfalize-0.8.2-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 d2c5fed5a973349ad743a19529d73397b52d9f4d532a607347cd6e33676d9ed2
MD5 1064e26c1a6f349ebbb885be3f96e598
BLAKE2b-256 51de805f46c5b75abe9e9ea45d9c2590c1f065c1574fdead28e53f99e2d7f513

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