Supported File Formats ====================== SurfaceTopography supports reading surface topography data from a wide variety of file formats commonly used by commercial profilometers, AFMs, and other surface measurement instruments. File Format Table ----------------- .. list-table:: :header-rows: 1 :widths: 30 20 50 * - Format Name - Extensions - Description * - Alicona Imaging AL3D - ``.al3d`` - AL3D format of Alicona Imaging optical 3D measurement systems * - BCR-STM - ``.bcr``, ``.bcrf`` - BCR-STM and BCRF file formats for scanning tunneling microscopy * - Bruker/Veeco/DI Nanoscope - ``.spm``, ``.001``-``.005`` - Digital Instruments, Veeco, and Bruker Dimension AFM formats * - Bruker Dektak OPDx - ``.opdx`` - File format of the Bruker Dektak XT series stylus profilometer * - Bruker Wyko OPD - ``.opd`` - Files generated by Vision software of Bruker Wyko white-light interferometers * - Digital Metrology OmniSurf3D - ``.os3d`` - OmniSurf3D format from Digital Metrology * - Digital Surf Mountains MNT - ``.mnt`` - Digital Surf Mountains OLE-based format with compressed height data (see :doc:`file_formats/MNT`) * - Digital Surf SUR - ``.sur`` - Digital Surf SUR data files * - Gwyddion - ``.gwy`` - Native file format of the open-source SPM visualization software Gwyddion * - Hierarchical Data Format (HDF5) - ``.h5`` - HDF5 files with 2D arrays (e.g., contact mechanics challenge data) * - Igor Binary Wave - ``.ibw`` - Igor binary wave container format (WaveMetrics Igor Pro) * - ISO 25178-71 SDF - ``.sdf`` - ISO 25178-71 Surface Data File format (ASCII and binary variants) * - JPK Image Scan - ``.jpk`` - TIFF-based file format of JPK instruments (now Bruker) * - Keyence VK - ``.vk3``, ``.vk4``, ``.vk6``, ``.vk7`` - VK3/VK4/VK6/VK7 formats of Keyence laser confocal microscopes * - Keyence ZON - ``.zon`` - ZON files from some Keyence instruments * - KLA Zeta - ``.zmg`` - KLA Zeta ZMG profilometry data files * - MATLAB - ``.mat`` - MATLAB workspace files containing topography data * - Microprof FRT - ``.frt`` - MicroProf FRT profilometry data * - Mitutoyo SurfTest - ``.xlsx`` - Excel spreadsheets from Mitutoyo SurfTest instruments * - Molecular Imaging (MI) - ``.mi`` - Agilent Technologies (Molecular Imaging) AFM format * - Nanofocus - ``.nms`` - Nanofocus NMS profilometry data files * - NanoSurf easyScan - ``.ezd``, ``.nid`` - NanoSurf easyScan data files * - Nanomeasuring Machine (NMM) - ``.zip`` - ZIP-packaged nanomeasuring machine files * - NASA SRTM - ``.hgt`` - NASA Shuttle Radar Topography Mission elevation data * - NetCDF - ``.nc`` - Network Common Data Format (classic and HDF5-based NetCDF4) * - NumPy Array - ``.npy`` - NumPy binary array format * - Olympus LEXT - ``.lext`` - TIFF-based format of Olympus LEXT confocal microscopes * - Olympus OIR - ``.oir`` - Olympus OIR data files * - Olympus Packed OIR - ``.poir`` - ZIP-packaged Olympus OIR files * - Park Systems TIFF - ``.tiff``, ``.tif`` - TIFF-based format of Park Systems AFM instruments * - Plain Text (ASCII) - ``.txt``, ``.asc``, ``.dat`` - Plain text files with optional headers * - Plain Text (XYZ) - ``.xyz``, ``.hfm``, ``.csv`` - Coordinate data as (x, y, z) tuples * - Sensofar PLU - ``.plu``, ``.apx`` - Sensofar SPM file format * - Sensofar PLUX - ``.plux`` - Sensofar XML-based SPM file format * - TrueMap - ``.tmd`` - TrueMap TMD profilometry data files * - WSxM - ``.cur``, ``.stp``, ``.tom``, ``.top`` - WSxM SPM data files * - X3P - ``.x3p`` - ISO 5436-2 XML 3D surface profile container format * - Zygo DATX - ``.datx`` - Zygo DATX HDF5-based format * - Zygo MetroPro - ``.dat`` - Zygo MetroPro data files Container Formats ----------------- In addition to individual topography files, SurfaceTopography can read container formats that bundle multiple topographies: .. list-table:: :header-rows: 1 :widths: 30 20 50 * - Format Name - Extensions - Description * - contact.engineering - ``.zip`` - Digital surface twin containers from `contact.engineering `_ * - Keyence ZAG - ``.zag`` - Keyence ZAG container format Basic Usage ----------- .. code-block:: python from SurfaceTopography import open_topography, read_topography # Auto-detect format and open file reader = open_topography("measurement.vk4") topography = reader.topography() # Or read directly topography = read_topography("measurement.vk4") For formats that don't store physical sizes or units (e.g., NPY, HDF5), you must provide them: .. code-block:: python topography = read_topography("data.npy", physical_sizes=(10.0, 10.0), unit="um") Working with Channels --------------------- Many file formats support multiple data channels (e.g., height, phase, amplitude error). You can inspect available channels and select which one to load. Inspecting Channels +++++++++++++++++++ .. code-block:: python from SurfaceTopography import open_topography reader = open_topography("afm_scan.ibw") # List all channels for ch in reader.channels: print(f" {ch.name}: {ch.channel_id} (height={ch.is_height_channel})") # Access only height channels (backwards compatible) for ch in reader.height_channels: print(f" Height channel: {ch.name}") Channel Selection Methods +++++++++++++++++++++++++ There are three ways to select which channel to load: .. code-block:: python # Method 1: By channel index (default behavior) topo = reader.topography(channel_index=0) # Method 2: By stable channel ID (recommended for database storage) topo = reader.topography(channel_id="Height") # Method 3: By height channel index (backwards compatible, only counts height channels) topo = reader.topography(height_channel_index=0) Channel Properties ++++++++++++++++++ Each channel (:class:`ChannelInfo`) has the following properties: - ``name`` - Human-readable channel name from the file - ``channel_id`` - Stable unique identifier (e.g., "Height", "Phase#2" for duplicates) - ``is_height_channel`` - ``True`` if channel contains height/topography data - ``height_index`` - Index among height channels only (``None`` for non-height channels) - ``data_kind`` - Type of data (HEIGHT, VOLTAGE, PHASE, AMPLITUDE, etc.) - ``dim`` - Dimensionality (1 for line scans, 2 for maps) - ``nb_grid_pts`` - Number of grid points - ``physical_sizes`` - Physical dimensions - ``unit`` - Unit of measurement Stable Channel Identification +++++++++++++++++++++++++++++ For applications that store channel references in databases, use ``channel_id`` instead of ``channel_index``. The ``channel_id`` is: - **Stable**: Remains the same across different reads of the same file - **Order-independent**: Doesn't depend on the internal order channels appear - **Unique**: Automatically disambiguated for duplicate names (e.g., "Height#1", "Height#2") Example for database storage: .. code-block:: python # When saving to database, store the channel_id channel_to_store = reader.channels[0].channel_id # e.g., "Height" # Later, when loading from database topo = reader.topography(channel_id=channel_to_store) Migrating from Height Index to Channel ID +++++++++++++++++++++++++++++++++++++++++ For databases that previously stored ``height_channel_index`` values, utility functions are provided to convert between the old and new systems: .. code-block:: python from SurfaceTopography import open_topography reader = open_topography("scan.ibw") # Convert old height index to new channel_id old_index = 0 # stored in database new_id = reader.height_index_to_channel_id(old_index) # new_id is now something like "Height" or "ZSensor" # Convert back if needed (only works for height channels) recovered_index = reader.channel_id_to_height_index(new_id) assert recovered_index == old_index Migration script example: .. code-block:: python from SurfaceTopography import open_topography def migrate_database_entry(file_path, old_height_index): """Migrate a database entry from height_index to channel_id.""" reader = open_topography(file_path) new_channel_id = reader.height_index_to_channel_id(old_height_index) return new_channel_id # Example usage # old_entry = {"file": "scan.ibw", "channel": 0} # new_entry = {"file": "scan.ibw", "channel_id": migrate_database_entry("scan.ibw", 0)} Notes ----- - File format is auto-detected from file content (magic bytes) when possible - Some formats support multiple channels - use ``reader.channels`` to inspect - Most readers support both file paths and file-like objects - Some readers support MPI-parallel reading for large datasets