Matter42
PlatformTeamCareersDocsBlog
Sign inStart analyzing
PlatformTeamCareersDocsBlog
Sign inStart
Back to blog
Technical walkthroughPublicJuly 202610 min read

AFM beyond roughness: what Atlas can do with a surface map

One 1 µm scan of CVD MoS₂ triangles, pushed as far as it goes: artifact-matched leveling, roughness moments, counting 40 flakes at a 0.56 nm monolayer step, line profiles, and the QNM channels hiding in the same file.

An AFM scan usually gets reduced to a picture and a single number: show the topography, report RMS roughness, move on. The instrument measured more than that. It recorded a calibrated height field, (z=f(x,y)), and in this case adhesion, modulus, deformation, and dissipation at every pixel too.

This post takes one scan of CVD-grown MoS₂ and keeps asking it questions until it runs out of answers. Everything below — leveling, roughness, flake segmentation, a line profile, and nanomechanics — comes from the same file, analyzed with the same Atlas Blocks that run in the Matter42 app.

The scan

A 1 µm, 352×352 PeakForce QNM scan of MoS₂ triangles grown on SiO₂, taken on a Bruker Dimension Icon. The filename says "topography", but the .spm carries the full PeakForce channel set alongside the height sensor: Peak Force Error, DMT modulus, adhesion, indentation, and dissipation. That matters at the end.

0075_350_M1_1um352.0_00004.spm· PeakForce QNM · 352×352 · 1 µm

The sample is early-stage growth: discrete triangular islands that have nucleated but not yet merged into a continuous film. That morphology is the point. A scan of one large flake gives you a single edge and a single number; a field of separated triangles gives you a population, and populations are what growth work actually compares.

Parsing preserves the measurement

The parse-afm-surface Block reads Bruker .spm, calibrated scalar TIFF, and matrix or long-form CSV exports into a surface_map. Lateral coordinates keep their physical units, heights keep theirs, and invalid pixels stay in a quality mask. For Bruker files, Atlas also extracts the Z calibration, scan size, direction, rate, instrument, acquisition time, and the list of available channels.

Parsing does not level, offset, or rescale the stored heights. Plane subtraction and line correction happen later, as an explicit transform that gets persisted, so the original measurement is always available for review.

The reason for that separation: "make the image look flat" is not a neutral operation. A global plane fit through a scan that is half substrate and half raised material gets pulled toward the raised part and removes some of the step itself.

Level once, analyze many times

The workflow Atlas enforces is: parse, explore the raw heights as-is, run level-afm-surface once, then run everything else against the derived dataset with no further leveling.

level-afm-surface is the only Block that chooses a leveling method. It writes a new surface whose z already carries the corrected topography, stamps analysis.afm_preprocessing and afm_height_semantics="leveled", and links back to the parent. Downstream Blocks require that metadata and fail with a direct instruction if you hand them a raw parse.

There are three modes:

  • plane — ordinary tilt removal.
  • plane_line — plane plus per-row median flattening and scar/spike repair, for scans with mid-scan Z jumps or tip spikes.
  • plateau — plane, then re-fit through the lowest gradient-delimited plateau, so a raised terrace cannot tilt the reference into the step.

This scan needs plane_line, and it is worth being explicit about why, because the obvious choice for a stepped sample is plateau. The scan drifts row to row: the per-row medians span 3.2 nm, from −1.96 nm to +1.26 nm, across a field whose real features are half a nanometre tall. Nor is the drift smooth — a quarter of the way up the scan the row medians step by 0.43 nm between two adjacent lines, a mid-scan Z jump that leaves a hard-edged scar band across the plane-leveled image. Under plane or plateau that banding swamps the step — Sq comes out at 0.82 nm instead of 0.28 nm, and segmentation resolves a single height level, finding no flakes at all. The drift and the scar both have to go first.

Level AFM Surface

Per-row flattening is safe on this scan for a specific reason: the triangles cover only 20% of the field, so each row's median height is the substrate. Subtracting it removes drift without touching the flakes. That reasoning does not transfer. On a scan split roughly half-and-half between substrate and film, every row crosses both levels, the row median lands somewhere in between, and row flattening drags the two populations together until the step is no longer measurable. Same Block, same parameter, opposite outcome — which is why the mode is an explicit choice rather than a default.

Every Block from here down reads this one leveled dataset.

Roughness, and what the moments admit

analyze-afm-roughness reports Sa, Sq, Sz, skewness, and excess kurtosis from the stored leveled heights. No leveling parameter exists on the Block; the surface already carries its correction.

Analyze AFM Roughness

Skewness of +1.03 and excess kurtosis of +1.49 are the fingerprint of a mostly-flat surface carrying sparse raised features. A symmetric rough surface sits near zero on both. Positive skew means the tail runs upward, and heavy tails mean the tail is doing real work rather than being noise. That is a quantitative statement that something discrete is sitting on top of this substrate, available before you look at the image.

Sz deserves the same scrutiny. 3.50 nm is not a field-wide range; it is the distance between exactly two local extremes — a bright particle on the high side and, on the low side, a gouge about 1.3 nm deep near (0.51, 0.29) µm. The gouge is worth pausing on because it looks like a scan artifact and is not one: it repeats in the same columns across ten consecutive scan lines, which is how you tell a real pit cut into the substrate from a scan-line scar that lives on a single row. Leveling correctly left it in the data, and it quietly sets the floor of Sz.

This is the general use of the higher moments in AFM work. Two surfaces can share an Sq while one has symmetric noise and the other has sparse tall islands, deep pits, or a step. The moments are a cheap check on whether the headline number means what you think it means — and here they say the honest roughness question is per-level, not global. Segmentation answers it below: 0.156 nm on the substrate, 0.250 nm on the flakes.

Counting flakes, not just measuring one

For this sample the interesting questions are about the population: how many islands, how big, how much of the surface do they cover, and how tall are they? segment-afm-surface classifies the stored field into height levels and then into connected components.

Segment AFM Surface

That 0.556 nm is a monolayer. The step is measured by fitting each level its own plane and differencing them along their shared border, which is why it survives on a scan where the two populations overlap heavily in the histogram — the flakes are only a quarter of the pixels, so the height distribution has a shoulder rather than two clean peaks. The separability of 2.20 and step SNR of 3.09 both clear their thresholds of 2.0, but not by a wide margin, and the Block reports them so you can see that rather than having to trust the label.

The population numbers are the ones you would actually put in a growth notebook. Forty islands in one square micron is a nucleation density of 4 × 10⁹ cm⁻². The mean flake area of 0.0050 µm² corresponds to about a 108 nm edge on an equilateral triangle, the median to about 97 nm — and the gap between mean and median, visible as the right-skewed area histogram, says the population is still spread rather than uniform. Coverage is 19.9%, so the film is roughly a fifth of the way to coalescence.

Those four numbers move independently under process changes, which is what makes them worth separating. Raising temperature or precursor ratio can hold coverage fixed while trading many small islands for few large ones; that shows up as flake count and area shifting in opposite directions with coverage flat. The particle fraction came out at exactly zero here, which is its own result — on a contaminated sample it separates residue from real terraces so a few tall specks stop dominating Sz.

A line profile is a local measurement

Area statistics can hide a scratch, fold, trench, or contact edge. profile-afm-line samples any path in physical coordinates with quality-aware bilinear interpolation, on the same leveled dataset. If valid support is missing along the path, Atlas leaves a gap rather than bridging it with invented heights.

Here the path runs along y = 0.285 µm, chosen so a single line crosses everything this scan has to offer: two triangular islands with substrate between them, and then the gouge from the roughness section.

Profile AFM Line

The gouge is the payoff. It sits at 0.36–0.42 µm along the path, immediately after the second island's falling edge, and the profile gives it what the area statistics could not: a measured depth of 1.25 nm and a width of roughly 50 nm. That depth is two monolayers down into the substrate — a scratch, not a missing flake. Profiles earn their keep on exactly these questions, the ones segmentation cannot answer: pit and scratch dimensions, edge sharpness and tip-convolution width, whether an island top is flat or domed, trench sidewall shape, wrinkle amplitude, the transition length across a patterned interface.

The same file contains mechanics

Now the detail from the top. This "topography" export is a PeakForce QNM capture, and the .spm still holds the mechanical channels. analyze-nanomechanics reads them directly from the original file, applies the instrument calibration, computes robust distributions, and measures each property's correlation with plane-leveled topography.

Analyze Nanomechanics

That caveat is the interesting part, so it is worth being blunt about. Atlas will tell you a channel is undecodable, as it did for the log-modulus channel, but it will not tell you the acquisition was set up badly. The deformation and modulus figures here point at the setup — most likely a peak-force setpoint and sync-distance combination that has the tip pushing through a soft adsorbed layer rather than probing the MoS₂ — not at the material. Adhesion and dissipation are on believable scales and are the channels to reason from on this file.

The correlation numbers are what make that judgement possible. Every property correlates essentially not at all with height: modulus at −0.001, adhesion at −0.023, deformation at −0.007, dissipation at −0.091. Nothing here is topographic crosstalk. When mechanical contrast instead reproduces the topographic edge exactly, that is the signature of a tip or feedback artifact, and the correlation column is where you catch it.

On a properly configured scan the same Block answers questions the height channel cannot: whether a patch is residue or a genuine second layer, whether a grain boundary is mechanically distinct when its height contrast is weak, how stiffness distributions shift after annealing or functionalization. It reports what the file supports and nothing more — it will not infer a modulus from an ordinary tapping-mode height image, and it will not treat an uncalibrated channel as quantitative.

The ledger for one file

One 1 µm scan, parsed once, leveled once:

  • a persisted leveled surface with the leveling model and its justification recorded in metadata,
  • whole-field roughness plus third and fourth moments that flag sparse raised features before you look at the image, and an Sz traced to one particle and one real 1.3 nm gouge,
  • 40 triangular islands with a 0.556 nm monolayer step, 19.9% coverage, an area distribution, and per-level roughness,
  • a physical line profile across two islands and the gouge, measuring the pit at 1.25 nm deep and ~50 nm wide with full validity accounting,
  • and calibrated adhesion, dissipation, modulus, and deformation maps the filename never mentioned, two of which the data tells you not to trust.

There are AFM analyses Atlas does not do yet: power spectral density and correlation lengths, fractal metrics, force–distance curve fitting, dedicated grain-boundary segmentation. Flake shape is not yet quantified, so "triangular" is still your eye rather than a measured circularity or edge-angle distribution. QNM channels are analyzed from the raw .spm rather than persisted as separate surface_map datasets, and segmentation labels live in the report rather than as a derived dataset. Those are current boundaries, stated so you know where the tool ends.

The pieces are documented in Explore Data, Level AFM Surface, Analyze AFM Roughness, Segment AFM Surface, Profile AFM Line, Analyze Nanomechanics, and the AFM parsing guide. Every figure above was generated from the source file through the same Atlas analysis functions the Blocks run.

Matter42

Agentic AI workflows for thin film and 2D semiconductor characterization.

PlatformTeamCareersDocsBlog
LinkedInPrivacy PolicyTerms and Conditions

Copyright © 2026 Matter42. All rights reserved.

Matter42
PlatformTeamCareersDocsBlog
Sign inStart analyzing
PlatformTeamCareersDocsBlog
Sign inStart
Back to blog
Technical walkthroughPublicJuly 202610 min read

AFM beyond roughness: what Atlas can do with a surface map

One 1 µm scan of CVD MoS₂ triangles, pushed as far as it goes: artifact-matched leveling, roughness moments, counting 40 flakes at a 0.56 nm monolayer step, line profiles, and the QNM channels hiding in the same file.

An AFM scan usually gets reduced to a picture and a single number: show the topography, report RMS roughness, move on. The instrument measured more than that. It recorded a calibrated height field, (z=f(x,y)), and in this case adhesion, modulus, deformation, and dissipation at every pixel too.

This post takes one scan of CVD-grown MoS₂ and keeps asking it questions until it runs out of answers. Everything below — leveling, roughness, flake segmentation, a line profile, and nanomechanics — comes from the same file, analyzed with the same Atlas Blocks that run in the Matter42 app.

The scan

A 1 µm, 352×352 PeakForce QNM scan of MoS₂ triangles grown on SiO₂, taken on a Bruker Dimension Icon. The filename says "topography", but the .spm carries the full PeakForce channel set alongside the height sensor: Peak Force Error, DMT modulus, adhesion, indentation, and dissipation. That matters at the end.

0075_350_M1_1um352.0_00004.spm· PeakForce QNM · 352×352 · 1 µm

The sample is early-stage growth: discrete triangular islands that have nucleated but not yet merged into a continuous film. That morphology is the point. A scan of one large flake gives you a single edge and a single number; a field of separated triangles gives you a population, and populations are what growth work actually compares.

Parsing preserves the measurement

The parse-afm-surface Block reads Bruker .spm, calibrated scalar TIFF, and matrix or long-form CSV exports into a surface_map. Lateral coordinates keep their physical units, heights keep theirs, and invalid pixels stay in a quality mask. For Bruker files, Atlas also extracts the Z calibration, scan size, direction, rate, instrument, acquisition time, and the list of available channels.

Parsing does not level, offset, or rescale the stored heights. Plane subtraction and line correction happen later, as an explicit transform that gets persisted, so the original measurement is always available for review.

The reason for that separation: "make the image look flat" is not a neutral operation. A global plane fit through a scan that is half substrate and half raised material gets pulled toward the raised part and removes some of the step itself.

Level once, analyze many times

The workflow Atlas enforces is: parse, explore the raw heights as-is, run level-afm-surface once, then run everything else against the derived dataset with no further leveling.

level-afm-surface is the only Block that chooses a leveling method. It writes a new surface whose z already carries the corrected topography, stamps analysis.afm_preprocessing and afm_height_semantics="leveled", and links back to the parent. Downstream Blocks require that metadata and fail with a direct instruction if you hand them a raw parse.

There are three modes:

  • plane — ordinary tilt removal.
  • plane_line — plane plus per-row median flattening and scar/spike repair, for scans with mid-scan Z jumps or tip spikes.
  • plateau — plane, then re-fit through the lowest gradient-delimited plateau, so a raised terrace cannot tilt the reference into the step.

This scan needs plane_line, and it is worth being explicit about why, because the obvious choice for a stepped sample is plateau. The scan drifts row to row: the per-row medians span 3.2 nm, from −1.96 nm to +1.26 nm, across a field whose real features are half a nanometre tall. Nor is the drift smooth — a quarter of the way up the scan the row medians step by 0.43 nm between two adjacent lines, a mid-scan Z jump that leaves a hard-edged scar band across the plane-leveled image. Under plane or plateau that banding swamps the step — Sq comes out at 0.82 nm instead of 0.28 nm, and segmentation resolves a single height level, finding no flakes at all. The drift and the scar both have to go first.

Level AFM Surface

Per-row flattening is safe on this scan for a specific reason: the triangles cover only 20% of the field, so each row's median height is the substrate. Subtracting it removes drift without touching the flakes. That reasoning does not transfer. On a scan split roughly half-and-half between substrate and film, every row crosses both levels, the row median lands somewhere in between, and row flattening drags the two populations together until the step is no longer measurable. Same Block, same parameter, opposite outcome — which is why the mode is an explicit choice rather than a default.

Every Block from here down reads this one leveled dataset.

Roughness, and what the moments admit

analyze-afm-roughness reports Sa, Sq, Sz, skewness, and excess kurtosis from the stored leveled heights. No leveling parameter exists on the Block; the surface already carries its correction.

Analyze AFM Roughness

Skewness of +1.03 and excess kurtosis of +1.49 are the fingerprint of a mostly-flat surface carrying sparse raised features. A symmetric rough surface sits near zero on both. Positive skew means the tail runs upward, and heavy tails mean the tail is doing real work rather than being noise. That is a quantitative statement that something discrete is sitting on top of this substrate, available before you look at the image.

Sz deserves the same scrutiny. 3.50 nm is not a field-wide range; it is the distance between exactly two local extremes — a bright particle on the high side and, on the low side, a gouge about 1.3 nm deep near (0.51, 0.29) µm. The gouge is worth pausing on because it looks like a scan artifact and is not one: it repeats in the same columns across ten consecutive scan lines, which is how you tell a real pit cut into the substrate from a scan-line scar that lives on a single row. Leveling correctly left it in the data, and it quietly sets the floor of Sz.

This is the general use of the higher moments in AFM work. Two surfaces can share an Sq while one has symmetric noise and the other has sparse tall islands, deep pits, or a step. The moments are a cheap check on whether the headline number means what you think it means — and here they say the honest roughness question is per-level, not global. Segmentation answers it below: 0.156 nm on the substrate, 0.250 nm on the flakes.

Counting flakes, not just measuring one

For this sample the interesting questions are about the population: how many islands, how big, how much of the surface do they cover, and how tall are they? segment-afm-surface classifies the stored field into height levels and then into connected components.

Segment AFM Surface

That 0.556 nm is a monolayer. The step is measured by fitting each level its own plane and differencing them along their shared border, which is why it survives on a scan where the two populations overlap heavily in the histogram — the flakes are only a quarter of the pixels, so the height distribution has a shoulder rather than two clean peaks. The separability of 2.20 and step SNR of 3.09 both clear their thresholds of 2.0, but not by a wide margin, and the Block reports them so you can see that rather than having to trust the label.

The population numbers are the ones you would actually put in a growth notebook. Forty islands in one square micron is a nucleation density of 4 × 10⁹ cm⁻². The mean flake area of 0.0050 µm² corresponds to about a 108 nm edge on an equilateral triangle, the median to about 97 nm — and the gap between mean and median, visible as the right-skewed area histogram, says the population is still spread rather than uniform. Coverage is 19.9%, so the film is roughly a fifth of the way to coalescence.

Those four numbers move independently under process changes, which is what makes them worth separating. Raising temperature or precursor ratio can hold coverage fixed while trading many small islands for few large ones; that shows up as flake count and area shifting in opposite directions with coverage flat. The particle fraction came out at exactly zero here, which is its own result — on a contaminated sample it separates residue from real terraces so a few tall specks stop dominating Sz.

A line profile is a local measurement

Area statistics can hide a scratch, fold, trench, or contact edge. profile-afm-line samples any path in physical coordinates with quality-aware bilinear interpolation, on the same leveled dataset. If valid support is missing along the path, Atlas leaves a gap rather than bridging it with invented heights.

Here the path runs along y = 0.285 µm, chosen so a single line crosses everything this scan has to offer: two triangular islands with substrate between them, and then the gouge from the roughness section.

Profile AFM Line

The gouge is the payoff. It sits at 0.36–0.42 µm along the path, immediately after the second island's falling edge, and the profile gives it what the area statistics could not: a measured depth of 1.25 nm and a width of roughly 50 nm. That depth is two monolayers down into the substrate — a scratch, not a missing flake. Profiles earn their keep on exactly these questions, the ones segmentation cannot answer: pit and scratch dimensions, edge sharpness and tip-convolution width, whether an island top is flat or domed, trench sidewall shape, wrinkle amplitude, the transition length across a patterned interface.

The same file contains mechanics

Now the detail from the top. This "topography" export is a PeakForce QNM capture, and the .spm still holds the mechanical channels. analyze-nanomechanics reads them directly from the original file, applies the instrument calibration, computes robust distributions, and measures each property's correlation with plane-leveled topography.

Analyze Nanomechanics

That caveat is the interesting part, so it is worth being blunt about. Atlas will tell you a channel is undecodable, as it did for the log-modulus channel, but it will not tell you the acquisition was set up badly. The deformation and modulus figures here point at the setup — most likely a peak-force setpoint and sync-distance combination that has the tip pushing through a soft adsorbed layer rather than probing the MoS₂ — not at the material. Adhesion and dissipation are on believable scales and are the channels to reason from on this file.

The correlation numbers are what make that judgement possible. Every property correlates essentially not at all with height: modulus at −0.001, adhesion at −0.023, deformation at −0.007, dissipation at −0.091. Nothing here is topographic crosstalk. When mechanical contrast instead reproduces the topographic edge exactly, that is the signature of a tip or feedback artifact, and the correlation column is where you catch it.

On a properly configured scan the same Block answers questions the height channel cannot: whether a patch is residue or a genuine second layer, whether a grain boundary is mechanically distinct when its height contrast is weak, how stiffness distributions shift after annealing or functionalization. It reports what the file supports and nothing more — it will not infer a modulus from an ordinary tapping-mode height image, and it will not treat an uncalibrated channel as quantitative.

The ledger for one file

One 1 µm scan, parsed once, leveled once:

  • a persisted leveled surface with the leveling model and its justification recorded in metadata,
  • whole-field roughness plus third and fourth moments that flag sparse raised features before you look at the image, and an Sz traced to one particle and one real 1.3 nm gouge,
  • 40 triangular islands with a 0.556 nm monolayer step, 19.9% coverage, an area distribution, and per-level roughness,
  • a physical line profile across two islands and the gouge, measuring the pit at 1.25 nm deep and ~50 nm wide with full validity accounting,
  • and calibrated adhesion, dissipation, modulus, and deformation maps the filename never mentioned, two of which the data tells you not to trust.

There are AFM analyses Atlas does not do yet: power spectral density and correlation lengths, fractal metrics, force–distance curve fitting, dedicated grain-boundary segmentation. Flake shape is not yet quantified, so "triangular" is still your eye rather than a measured circularity or edge-angle distribution. QNM channels are analyzed from the raw .spm rather than persisted as separate surface_map datasets, and segmentation labels live in the report rather than as a derived dataset. Those are current boundaries, stated so you know where the tool ends.

The pieces are documented in Explore Data, Level AFM Surface, Analyze AFM Roughness, Segment AFM Surface, Profile AFM Line, Analyze Nanomechanics, and the AFM parsing guide. Every figure above was generated from the source file through the same Atlas analysis functions the Blocks run.

Matter42

Agentic AI workflows for thin film and 2D semiconductor characterization.

PlatformTeamCareersDocsBlog
LinkedInPrivacy PolicyTerms and Conditions

Copyright © 2026 Matter42. All rights reserved.

Matter42
PlatformTeamCareersDocsBlog
Sign inStart analyzing
PlatformTeamCareersDocsBlog
Sign inStart
Back to blog
Technical walkthroughPublicJuly 202610 min read

AFM beyond roughness: what Atlas can do with a surface map

One 1 µm scan of CVD MoS₂ triangles, pushed as far as it goes: artifact-matched leveling, roughness moments, counting 40 flakes at a 0.56 nm monolayer step, line profiles, and the QNM channels hiding in the same file.

An AFM scan usually gets reduced to a picture and a single number: show the topography, report RMS roughness, move on. The instrument measured more than that. It recorded a calibrated height field, (z=f(x,y)), and in this case adhesion, modulus, deformation, and dissipation at every pixel too.

This post takes one scan of CVD-grown MoS₂ and keeps asking it questions until it runs out of answers. Everything below — leveling, roughness, flake segmentation, a line profile, and nanomechanics — comes from the same file, analyzed with the same Atlas Blocks that run in the Matter42 app.

The scan

A 1 µm, 352×352 PeakForce QNM scan of MoS₂ triangles grown on SiO₂, taken on a Bruker Dimension Icon. The filename says "topography", but the .spm carries the full PeakForce channel set alongside the height sensor: Peak Force Error, DMT modulus, adhesion, indentation, and dissipation. That matters at the end.

0075_350_M1_1um352.0_00004.spm· PeakForce QNM · 352×352 · 1 µm

The sample is early-stage growth: discrete triangular islands that have nucleated but not yet merged into a continuous film. That morphology is the point. A scan of one large flake gives you a single edge and a single number; a field of separated triangles gives you a population, and populations are what growth work actually compares.

Parsing preserves the measurement

The parse-afm-surface Block reads Bruker .spm, calibrated scalar TIFF, and matrix or long-form CSV exports into a surface_map. Lateral coordinates keep their physical units, heights keep theirs, and invalid pixels stay in a quality mask. For Bruker files, Atlas also extracts the Z calibration, scan size, direction, rate, instrument, acquisition time, and the list of available channels.

Parsing does not level, offset, or rescale the stored heights. Plane subtraction and line correction happen later, as an explicit transform that gets persisted, so the original measurement is always available for review.

The reason for that separation: "make the image look flat" is not a neutral operation. A global plane fit through a scan that is half substrate and half raised material gets pulled toward the raised part and removes some of the step itself.

Level once, analyze many times

The workflow Atlas enforces is: parse, explore the raw heights as-is, run level-afm-surface once, then run everything else against the derived dataset with no further leveling.

level-afm-surface is the only Block that chooses a leveling method. It writes a new surface whose z already carries the corrected topography, stamps analysis.afm_preprocessing and afm_height_semantics="leveled", and links back to the parent. Downstream Blocks require that metadata and fail with a direct instruction if you hand them a raw parse.

There are three modes:

Matter42

Agentic AI workflows for thin film and 2D semiconductor characterization.

PlatformTeamCareersDocsBlog
LinkedInPrivacy PolicyTerms and Conditions

Copyright © 2026 Matter42. All rights reserved.

Matter42
PlatformTeamCareersDocsBlog
Sign inStart analyzing
PlatformTeamCareersDocsBlog
Sign inStart
Back to blog
Technical walkthroughPublicJuly 202610 min read

AFM beyond roughness: what Atlas can do with a surface map

One 1 µm scan of CVD MoS₂ triangles, pushed as far as it goes: artifact-matched leveling, roughness moments, counting 40 flakes at a 0.56 nm monolayer step, line profiles, and the QNM channels hiding in the same file.

An AFM scan usually gets reduced to a picture and a single number: show the topography, report RMS roughness, move on. The instrument measured more than that. It recorded a calibrated height field, (z=f(x,y)), and in this case adhesion, modulus, deformation, and dissipation at every pixel too.

This post takes one scan of CVD-grown MoS₂ and keeps asking it questions until it runs out of answers. Everything below — leveling, roughness, flake segmentation, a line profile, and nanomechanics — comes from the same file, analyzed with the same Atlas Blocks that run in the Matter42 app.

The scan

A 1 µm, 352×352 PeakForce QNM scan of MoS₂ triangles grown on SiO₂, taken on a Bruker Dimension Icon. The filename says "topography", but the .spm carries the full PeakForce channel set alongside the height sensor: Peak Force Error, DMT modulus, adhesion, indentation, and dissipation. That matters at the end.

0075_350_M1_1um352.0_00004.spm· PeakForce QNM · 352×352 · 1 µm

The sample is early-stage growth: discrete triangular islands that have nucleated but not yet merged into a continuous film. That morphology is the point. A scan of one large flake gives you a single edge and a single number; a field of separated triangles gives you a population, and populations are what growth work actually compares.

Parsing preserves the measurement

The parse-afm-surface Block reads Bruker .spm, calibrated scalar TIFF, and matrix or long-form CSV exports into a surface_map. Lateral coordinates keep their physical units, heights keep theirs, and invalid pixels stay in a quality mask. For Bruker files, Atlas also extracts the Z calibration, scan size, direction, rate, instrument, acquisition time, and the list of available channels.

Parsing does not level, offset, or rescale the stored heights. Plane subtraction and line correction happen later, as an explicit transform that gets persisted, so the original measurement is always available for review.

The reason for that separation: "make the image look flat" is not a neutral operation. A global plane fit through a scan that is half substrate and half raised material gets pulled toward the raised part and removes some of the step itself.

Level once, analyze many times

The workflow Atlas enforces is: parse, explore the raw heights as-is, run level-afm-surface once, then run everything else against the derived dataset with no further leveling.

level-afm-surface is the only Block that chooses a leveling method. It writes a new surface whose z already carries the corrected topography, stamps analysis.afm_preprocessing and afm_height_semantics="leveled", and links back to the parent. Downstream Blocks require that metadata and fail with a direct instruction if you hand them a raw parse.

There are three modes:

Matter42

Agentic AI workflows for thin film and 2D semiconductor characterization.

PlatformTeamCareersDocsBlog
LinkedInPrivacy PolicyTerms and Conditions

Copyright © 2026 Matter42. All rights reserved.

  • plane — ordinary tilt removal.
  • plane_line — plane plus per-row median flattening and scar/spike repair, for scans with mid-scan Z jumps or tip spikes.
  • plateau — plane, then re-fit through the lowest gradient-delimited plateau, so a raised terrace cannot tilt the reference into the step.

This scan needs plane_line, and it is worth being explicit about why, because the obvious choice for a stepped sample is plateau. The scan drifts row to row: the per-row medians span 3.2 nm, from −1.96 nm to +1.26 nm, across a field whose real features are half a nanometre tall. Nor is the drift smooth — a quarter of the way up the scan the row medians step by 0.43 nm between two adjacent lines, a mid-scan Z jump that leaves a hard-edged scar band across the plane-leveled image. Under plane or plateau that banding swamps the step — Sq comes out at 0.82 nm instead of 0.28 nm, and segmentation resolves a single height level, finding no flakes at all. The drift and the scar both have to go first.

Level AFM Surface

Per-row flattening is safe on this scan for a specific reason: the triangles cover only 20% of the field, so each row's median height is the substrate. Subtracting it removes drift without touching the flakes. That reasoning does not transfer. On a scan split roughly half-and-half between substrate and film, every row crosses both levels, the row median lands somewhere in between, and row flattening drags the two populations together until the step is no longer measurable. Same Block, same parameter, opposite outcome — which is why the mode is an explicit choice rather than a default.

Every Block from here down reads this one leveled dataset.

Roughness, and what the moments admit

analyze-afm-roughness reports Sa, Sq, Sz, skewness, and excess kurtosis from the stored leveled heights. No leveling parameter exists on the Block; the surface already carries its correction.

  • plane — ordinary tilt removal.
  • plane_line — plane plus per-row median flattening and scar/spike repair, for scans with mid-scan Z jumps or tip spikes.
  • plateau — plane, then re-fit through the lowest gradient-delimited plateau, so a raised terrace cannot tilt the reference into the step.

This scan needs plane_line, and it is worth being explicit about why, because the obvious choice for a stepped sample is plateau. The scan drifts row to row: the per-row medians span 3.2 nm, from −1.96 nm to +1.26 nm, across a field whose real features are half a nanometre tall. Nor is the drift smooth — a quarter of the way up the scan the row medians step by 0.43 nm between two adjacent lines, a mid-scan Z jump that leaves a hard-edged scar band across the plane-leveled image. Under plane or plateau that banding swamps the step — Sq comes out at 0.82 nm instead of 0.28 nm, and segmentation resolves a single height level, finding no flakes at all. The drift and the scar both have to go first.

Level AFM Surface

Per-row flattening is safe on this scan for a specific reason: the triangles cover only 20% of the field, so each row's median height is the substrate. Subtracting it removes drift without touching the flakes. That reasoning does not transfer. On a scan split roughly half-and-half between substrate and film, every row crosses both levels, the row median lands somewhere in between, and row flattening drags the two populations together until the step is no longer measurable. Same Block, same parameter, opposite outcome — which is why the mode is an explicit choice rather than a default.

Every Block from here down reads this one leveled dataset.

Roughness, and what the moments admit

analyze-afm-roughness reports Sa, Sq, Sz, skewness, and excess kurtosis from the stored leveled heights. No leveling parameter exists on the Block; the surface already carries its correction.

Analyze AFM Roughness

Skewness of +1.03 and excess kurtosis of +1.49 are the fingerprint of a mostly-flat surface carrying sparse raised features. A symmetric rough surface sits near zero on both. Positive skew means the tail runs upward, and heavy tails mean the tail is doing real work rather than being noise. That is a quantitative statement that something discrete is sitting on top of this substrate, available before you look at the image.

Sz deserves the same scrutiny. 3.50 nm is not a field-wide range; it is the distance between exactly two local extremes — a bright particle on the high side and, on the low side, a gouge about 1.3 nm deep near (0.51, 0.29) µm. The gouge is worth pausing on because it looks like a scan artifact and is not one: it repeats in the same columns across ten consecutive scan lines, which is how you tell a real pit cut into the substrate from a scan-line scar that lives on a single row. Leveling correctly left it in the data, and it quietly sets the floor of Sz.

This is the general use of the higher moments in AFM work. Two surfaces can share an Sq while one has symmetric noise and the other has sparse tall islands, deep pits, or a step. The moments are a cheap check on whether the headline number means what you think it means — and here they say the honest roughness question is per-level, not global. Segmentation answers it below: 0.156 nm on the substrate, 0.250 nm on the flakes.

Counting flakes, not just measuring one

For this sample the interesting questions are about the population: how many islands, how big, how much of the surface do they cover, and how tall are they? segment-afm-surface classifies the stored field into height levels and then into connected components.

Analyze AFM Roughness

Skewness of +1.03 and excess kurtosis of +1.49 are the fingerprint of a mostly-flat surface carrying sparse raised features. A symmetric rough surface sits near zero on both. Positive skew means the tail runs upward, and heavy tails mean the tail is doing real work rather than being noise. That is a quantitative statement that something discrete is sitting on top of this substrate, available before you look at the image.

Sz deserves the same scrutiny. 3.50 nm is not a field-wide range; it is the distance between exactly two local extremes — a bright particle on the high side and, on the low side, a gouge about 1.3 nm deep near (0.51, 0.29) µm. The gouge is worth pausing on because it looks like a scan artifact and is not one: it repeats in the same columns across ten consecutive scan lines, which is how you tell a real pit cut into the substrate from a scan-line scar that lives on a single row. Leveling correctly left it in the data, and it quietly sets the floor of Sz.

This is the general use of the higher moments in AFM work. Two surfaces can share an Sq while one has symmetric noise and the other has sparse tall islands, deep pits, or a step. The moments are a cheap check on whether the headline number means what you think it means — and here they say the honest roughness question is per-level, not global. Segmentation answers it below: 0.156 nm on the substrate, 0.250 nm on the flakes.

Counting flakes, not just measuring one

For this sample the interesting questions are about the population: how many islands, how big, how much of the surface do they cover, and how tall are they? segment-afm-surface classifies the stored field into height levels and then into connected components.

Segment AFM Surface
Segment AFM Surface

That 0.556 nm is a monolayer. The step is measured by fitting each level its own plane and differencing them along their shared border, which is why it survives on a scan where the two populations overlap heavily in the histogram — the flakes are only a quarter of the pixels, so the height distribution has a shoulder rather than two clean peaks. The separability of 2.20 and step SNR of 3.09 both clear their thresholds of 2.0, but not by a wide margin, and the Block reports them so you can see that rather than having to trust the label.

The population numbers are the ones you would actually put in a growth notebook. Forty islands in one square micron is a nucleation density of 4 × 10⁹ cm⁻². The mean flake area of 0.0050 µm² corresponds to about a 108 nm edge on an equilateral triangle, the median to about 97 nm — and the gap between mean and median, visible as the right-skewed area histogram, says the population is still spread rather than uniform. Coverage is 19.9%, so the film is roughly a fifth of the way to coalescence.

Those four numbers move independently under process changes, which is what makes them worth separating. Raising temperature or precursor ratio can hold coverage fixed while trading many small islands for few large ones; that shows up as flake count and area shifting in opposite directions with coverage flat. The particle fraction came out at exactly zero here, which is its own result — on a contaminated sample it separates residue from real terraces so a few tall specks stop dominating Sz.

A line profile is a local measurement

Area statistics can hide a scratch, fold, trench, or contact edge. profile-afm-line samples any path in physical coordinates with quality-aware bilinear interpolation, on the same leveled dataset. If valid support is missing along the path, Atlas leaves a gap rather than bridging it with invented heights.

Here the path runs along y = 0.285 µm, chosen so a single line crosses everything this scan has to offer: two triangular islands with substrate between them, and then the gouge from the roughness section.

Profile AFM Line

That 0.556 nm is a monolayer. The step is measured by fitting each level its own plane and differencing them along their shared border, which is why it survives on a scan where the two populations overlap heavily in the histogram — the flakes are only a quarter of the pixels, so the height distribution has a shoulder rather than two clean peaks. The separability of 2.20 and step SNR of 3.09 both clear their thresholds of 2.0, but not by a wide margin, and the Block reports them so you can see that rather than having to trust the label.

The population numbers are the ones you would actually put in a growth notebook. Forty islands in one square micron is a nucleation density of 4 × 10⁹ cm⁻². The mean flake area of 0.0050 µm² corresponds to about a 108 nm edge on an equilateral triangle, the median to about 97 nm — and the gap between mean and median, visible as the right-skewed area histogram, says the population is still spread rather than uniform. Coverage is 19.9%, so the film is roughly a fifth of the way to coalescence.

Those four numbers move independently under process changes, which is what makes them worth separating. Raising temperature or precursor ratio can hold coverage fixed while trading many small islands for few large ones; that shows up as flake count and area shifting in opposite directions with coverage flat. The particle fraction came out at exactly zero here, which is its own result — on a contaminated sample it separates residue from real terraces so a few tall specks stop dominating Sz.

A line profile is a local measurement

Area statistics can hide a scratch, fold, trench, or contact edge. profile-afm-line samples any path in physical coordinates with quality-aware bilinear interpolation, on the same leveled dataset. If valid support is missing along the path, Atlas leaves a gap rather than bridging it with invented heights.

Here the path runs along y = 0.285 µm, chosen so a single line crosses everything this scan has to offer: two triangular islands with substrate between them, and then the gouge from the roughness section.

Profile AFM Line

The gouge is the payoff. It sits at 0.36–0.42 µm along the path, immediately after the second island's falling edge, and the profile gives it what the area statistics could not: a measured depth of 1.25 nm and a width of roughly 50 nm. That depth is two monolayers down into the substrate — a scratch, not a missing flake. Profiles earn their keep on exactly these questions, the ones segmentation cannot answer: pit and scratch dimensions, edge sharpness and tip-convolution width, whether an island top is flat or domed, trench sidewall shape, wrinkle amplitude, the transition length across a patterned interface.

The same file contains mechanics

Now the detail from the top. This "topography" export is a PeakForce QNM capture, and the .spm still holds the mechanical channels. analyze-nanomechanics reads them directly from the original file, applies the instrument calibration, computes robust distributions, and measures each property's correlation with plane-leveled topography.

Analyze Nanomechanics

That caveat is the interesting part, so it is worth being blunt about. Atlas will tell you a channel is undecodable, as it did for the log-modulus channel, but it will not tell you the acquisition was set up badly. The deformation and modulus figures here point at the setup — most likely a peak-force setpoint and sync-distance combination that has the tip pushing through a soft adsorbed layer rather than probing the MoS₂ — not at the material. Adhesion and dissipation are on believable scales and are the channels to reason from on this file.

The correlation numbers are what make that judgement possible. Every property correlates essentially not at all with height: modulus at −0.001, adhesion at −0.023, deformation at −0.007, dissipation at −0.091. Nothing here is topographic crosstalk. When mechanical contrast instead reproduces the topographic edge exactly, that is the signature of a tip or feedback artifact, and the correlation column is where you catch it.

On a properly configured scan the same Block answers questions the height channel cannot: whether a patch is residue or a genuine second layer, whether a grain boundary is mechanically distinct when its height contrast is weak, how stiffness distributions shift after annealing or functionalization. It reports what the file supports and nothing more — it will not infer a modulus from an ordinary tapping-mode height image, and it will not treat an uncalibrated channel as quantitative.

The ledger for one file

One 1 µm scan, parsed once, leveled once:

The gouge is the payoff. It sits at 0.36–0.42 µm along the path, immediately after the second island's falling edge, and the profile gives it what the area statistics could not: a measured depth of 1.25 nm and a width of roughly 50 nm. That depth is two monolayers down into the substrate — a scratch, not a missing flake. Profiles earn their keep on exactly these questions, the ones segmentation cannot answer: pit and scratch dimensions, edge sharpness and tip-convolution width, whether an island top is flat or domed, trench sidewall shape, wrinkle amplitude, the transition length across a patterned interface.

The same file contains mechanics

Now the detail from the top. This "topography" export is a PeakForce QNM capture, and the .spm still holds the mechanical channels. analyze-nanomechanics reads them directly from the original file, applies the instrument calibration, computes robust distributions, and measures each property's correlation with plane-leveled topography.

Analyze Nanomechanics

That caveat is the interesting part, so it is worth being blunt about. Atlas will tell you a channel is undecodable, as it did for the log-modulus channel, but it will not tell you the acquisition was set up badly. The deformation and modulus figures here point at the setup — most likely a peak-force setpoint and sync-distance combination that has the tip pushing through a soft adsorbed layer rather than probing the MoS₂ — not at the material. Adhesion and dissipation are on believable scales and are the channels to reason from on this file.

The correlation numbers are what make that judgement possible. Every property correlates essentially not at all with height: modulus at −0.001, adhesion at −0.023, deformation at −0.007, dissipation at −0.091. Nothing here is topographic crosstalk. When mechanical contrast instead reproduces the topographic edge exactly, that is the signature of a tip or feedback artifact, and the correlation column is where you catch it.

On a properly configured scan the same Block answers questions the height channel cannot: whether a patch is residue or a genuine second layer, whether a grain boundary is mechanically distinct when its height contrast is weak, how stiffness distributions shift after annealing or functionalization. It reports what the file supports and nothing more — it will not infer a modulus from an ordinary tapping-mode height image, and it will not treat an uncalibrated channel as quantitative.

The ledger for one file

One 1 µm scan, parsed once, leveled once:

  • a persisted leveled surface with the leveling model and its justification recorded in metadata,
  • whole-field roughness plus third and fourth moments that flag sparse raised features before you look at the image, and an Sz traced to one particle and one real 1.3 nm gouge,
  • 40 triangular islands with a 0.556 nm monolayer step, 19.9% coverage, an area distribution, and per-level roughness,
  • a physical line profile across two islands and the gouge, measuring the pit at 1.25 nm deep and ~50 nm wide with full validity accounting,
  • and calibrated adhesion, dissipation, modulus, and deformation maps the filename never mentioned, two of which the data tells you not to trust.

There are AFM analyses Atlas does not do yet: power spectral density and correlation lengths, fractal metrics, force–distance curve fitting, dedicated grain-boundary segmentation. Flake shape is not yet quantified, so "triangular" is still your eye rather than a measured circularity or edge-angle distribution. QNM channels are analyzed from the raw .spm rather than persisted as separate surface_map datasets, and segmentation labels live in the report rather than as a derived dataset. Those are current boundaries, stated so you know where the tool ends.

The pieces are documented in Explore Data, Level AFM Surface, Analyze AFM Roughness, Segment AFM Surface, Profile AFM Line, Analyze Nanomechanics, and the AFM parsing guide. Every figure above was generated from the source file through the same Atlas analysis functions the Blocks run.

  • a persisted leveled surface with the leveling model and its justification recorded in metadata,
  • whole-field roughness plus third and fourth moments that flag sparse raised features before you look at the image, and an Sz traced to one particle and one real 1.3 nm gouge,
  • 40 triangular islands with a 0.556 nm monolayer step, 19.9% coverage, an area distribution, and per-level roughness,
  • a physical line profile across two islands and the gouge, measuring the pit at 1.25 nm deep and ~50 nm wide with full validity accounting,
  • and calibrated adhesion, dissipation, modulus, and deformation maps the filename never mentioned, two of which the data tells you not to trust.

There are AFM analyses Atlas does not do yet: power spectral density and correlation lengths, fractal metrics, force–distance curve fitting, dedicated grain-boundary segmentation. Flake shape is not yet quantified, so "triangular" is still your eye rather than a measured circularity or edge-angle distribution. QNM channels are analyzed from the raw .spm rather than persisted as separate surface_map datasets, and segmentation labels live in the report rather than as a derived dataset. Those are current boundaries, stated so you know where the tool ends.

The pieces are documented in Explore Data, Level AFM Surface, Analyze AFM Roughness, Segment AFM Surface, Profile AFM Line, Analyze Nanomechanics, and the AFM parsing guide. Every figure above was generated from the source file through the same Atlas analysis functions the Blocks run.