This release has been yanked by its maintainers, and will be ignored by installers, except when explicitly specified.
Consider using release 2.2.4 instead.
NSFopen
Open and analyze Nanosurf NID and NHF files in Python: images, force spectroscopy and WaveMode NMA.
What's new in 2.3.0
Compared to 2.2.4, the previous version on PyPI:
- Works by itself: the
nanosurfandscikit-learnpackages are no longer needed. - NHF spectroscopy and WaveMode NMA: files of any size open immediately, and curves are read when asked for.
- Image analysis from the Nanosurf Surface Analyzer: leveling, filters, masks, ISO statistics, line cuts, step heights, critical dimension, PSD fits, lattice and grains.
- Better figures: units and labels from the file, subplots with
ax=, a new 3D plot, and plots of the analysis results. - Examples rewritten, with several bugs fixed. The
Spring_Constantresult changes from 14.5 to 24.0 N/m, because the old fit used the wrong formula.
Some defaults changed, which can affect existing scripts:
- NHF force curves
[row, col]now give the true grid position. imageandhistchoose their unit from the channel;scale=1e9still forces nm.imageshows a color bar unlesscolorbar=False.remove_outliersgives different numbers and no longer takesneighbors.
CHANGELOG.md, in the source distribution, has the full list.
Installing
From PyPi
pip install NSFopen
Needs numpy, scipy, pandas, h5py and matplotlib 3.6 or newer. Examples are in the example folder; NSFopen_help shows where. Each
is a notebook with its .py and .html, to run from its own folder:
| Example | Shows |
|---|---|
Plotting_Data |
Leveling with a mask, figures for a report, subplots, 3D |
Calculate_Roughness |
Surface statistics, height distribution, bearing curve, PSD, roughness along a line |
Plane_Removal |
Leveling all the files of a folder |
Grain_Analysis |
Finding features and measuring each of them |
Lateral_Force |
Friction from the forward and backward scans |
Force_Spectroscopy |
Fitting a force map with the DMT model |
Spring_Constant |
Sader method from a thermal tune |
Sharpen_Image |
Your own processing on the arrays, stored back as channels |
Reading files
from NSFopen.read import read
afm = read('filename.nid') # or .nhf
afm.data['Image']['Forward']['Z-Axis'] # an image, in SI units
afm.param # parameters of the file
afm.units[('Image', 'Forward', 'Z-Axis')]
Row 0 of an image is the first line scanned, which is the bottom of the picture for an upward scan.
Spectroscopy (.nhf)
Files of any size open immediately: curves are read when you ask for them.
afm = read('grid.nhf')
afm.spec.segments, afm.spec.shape, afm.spec.n_points
deflection = afm.spec['Retract 1']['Deflection']
deflection[10] # 11th curve in acquisition order
deflection[2, 3] # curve at row 2, column 3 of the grid, row 0 at the bottom
deflection.to('m')[2, 3] # in another unit, if the file holds its calibration
deflection.curves() # all curves, which may differ in length
deflection.array() # all curves as (rows, columns, samples), padded with NaN
z, force = afm.spec.force_curve('Retract 1', (2, 3))
afm.close()
afm.data['Spec']['Retract 1']['Deflection'] is the same object.
WaveMode NMA (.nhf)
The scalar channels are in afm.data as for any image, the per-pixel curves in afm.nma.
afm = read('nma.nhf')
curve = afm.nma.curve((100, 200), scan='Forward') # row, column
curve.z, curve.interaction, curve.force
z_advance, force_advance = curve.advance
z_retract, force_retract = curve.retract
adhesion = afm.nma.map() # most negative interaction of every pixel, in V
stiff = afm.nma.map(lambda block: block.max(axis=1), scan='Backward') # any function of (pixels, samples)
Processing images
from NSFopen.process import process
afm = process('filename.nhf')
afm.level_flatten() # align the lines, then subtract a plane
afm.mask_otsu() # two-level image: mask the upper level
afm.flatten(fit_on='exclude') # level the lines on what is not masked
afm.statistics(region='unmasked') # Sa, Sq, Ssk, Sku, Sdq, Sdr, Sal, Str, ... with units
grains = afm.grains(split='height') # one row per grain in grains.table
profile = afm.line_profile((0, 1e-6), (2e-6, 1e-6), width=5) # end points in m
afm.step_heights(profile).steps
afm.critical_dimension(profile).features
afm.profile_roughness(profile).params # ISO 21920
afm.psd_fit().summary() # corner, power law, noise floor, resolution
afm.lattice().summary()
afm.image(show_mask=True)
afm.hist()
afm.plot3d() # 3D, colored by height
afm.plot3d(material='Gold', tilt=60) # 3D, a material under a light
afm.plot3d(color='Phase') # 3D, colored by another channel
afm.array() gives a channel as an array and afm.set_channel(values, channel='Name', unit='m') stores your own array
as a channel, for all the functions below.
All processing works on one channel, by default direction='Forward' and the height, which files call Z-Axis or
Topography; afm.channels lists them all. It changes the channel unless inplace=False, when the new array is
returned instead.
| Group | Methods |
|---|---|
| Leveling | flatten, plane_level, level_flatten, level_poly2d, level_lines, level_align_rows, level_facet, level_three_point, level_median, level_rolling_ball, level_shift |
| Filters | denoise, filter_basic, filter_median, filter_gaussian, filter_fft, filter_notch |
| Glitches | remove_outliers, glitch_spikes, glitch_lines, glitch_auto_lines, glitch_scars, glitch_step_lines, glitch_fill_mask |
| Masks | set_mask, mask_threshold, mask_otsu, mask_watershed, mask_outliers, mask_scars, mask_shape, mask_floodfill, mask_grow, mask_shrink, mask_invert, mask_clear, mask_remove_small, mask_fill_holes |
| Geometry and scale | geometry_crop, geometry_flip, geometry_rotate, geometry_resample, geometry_square_pixels, rescale_scale, rescale_z_to_reference, rescale_xy |
| Height statistics | stats, statistics, bearing_curve, histogram_fit, slope_distributions |
| Lines | line_profile, step_heights, critical_dimension, profile_roughness, masked_step_height |
| Spectra and texture | psd, psd_fit, spectrum, acf, line_functions, rms_by_scale, lattice |
| Grains | grains |
| Two channels | combine, find_shift |
| Plots | image, thumb, hist, plot3d, plot_profile, plot_psd, plot_histogram_fit, plot_bearing, plot_acf |
help(process.level_rolling_ball) explains a method and its parameters; process.operations() lists the operations
with their defaults.
Figures
image, hist, thumb and plot3d take a channel and return a matplotlib figure, with the unit (nm, mV, ...) and
labels from the file.
fig = afm.image(channel='Phase', color_range='p1', cmap='viridis') # color range: 'full', 'p1' (1-99 %) or (low, high)
fig.savefig('phase.png')
afm.image(scalebar=True, title=None, figsize=(4, 4), dpi=600, theme='dark')
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 3, figsize=(12, 4), layout='constrained')
afm.image(ax=axes[0])
afm.hist(ax=axes[1])
afm.plot3d(material='Gold', ax=axes[2])
Results of the analysis have their plots too, with the same options:
profile = afm.line_profile((0, 1e-6), (2e-6, 1e-6), width=5)
afm.image(profile=profile) # where the line is
afm.plot_profile(profile, steps=afm.step_heights(profile)) # or cd=afm.critical_dimension(profile)
afm.plot_psd() # with a fit; fit=None for the data alone
afm.plot_histogram_fit(model='gauss2')
afm.plot_bearing()
afm.plot_acf()
Color maps
from NSFopen.process import colors
afm.image(cmap='Gold') # by name
afm.image(cmap=colors('Gold').cmap)
The Gwyddion gradients are included with the package.
Metadata
Release files for NSFopen 2.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| nsfopen-2.3.0.tar.gz | 23.1 MB | Without provenance | Details for nsfopen-2.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| nsfopen-2.3.0-py3-none-any.whl | Python 3 | none | any | Details for nsfopen-2.3.0-py3-none-any.whl |
Total release size: 46.2 MB
Release files / nsfopen-2.3.0.tar.gz
| Download URL | nsfopen-2.3.0.tar.gz |
|---|---|
| Size | 23.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6b054880c902efb9fb1d42106caaff0eac5be9a19a14046014d2bf3bcdcab402
|
|
BLAKE2b-256 checksum How to use checksums |
bee69896f163e93d1d84f16ce27d4ec1ab80c4111ed7b24bc7cb3f36162d1c70
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|
Release files / nsfopen-2.3.0-py3-none-any.whl
| Download URL | nsfopen-2.3.0-py3-none-any.whl |
|---|---|
| Size | 23.1 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2c179a1116c4a77259776c18b58488db43bc0a4a2f706a2a5a5da64d9ef4edcf
|
|
BLAKE2b-256 checksum How to use checksums |
f89bfe1ff337c6f3231e4857e532a3147fa769956ab53e7e54f289b2f9f3c768
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|
Security for NSFopen 2.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.