Library

SMLMData.SMLMDataModule
SMLMData

A Julia package for working with Single Molecule Localization Microscopy (SMLM) data.

Features

  • Type system for emitters, cameras, and localization data
  • Physical coordinate handling (microns) with camera pixel mappings
  • Filtering and ROI selection tools
  • SMITE format compatibility
  • Memory-efficient data structures

Basic Usage

using SMLMData

# Create a camera
cam = IdealCamera(1:512, 1:512, 0.1)  # 512x512 camera with 0.1 micron pixels

# Create some emitters
emitters = [
    Emitter2DFit{Float64}(1.0, 2.0, 1000.0, 10.0, 0.01, 0.01, 50.0, 2.0),
    Emitter2DFit{Float64}(3.0, 4.0, 1200.0, 12.0, 0.01, 0.01, 60.0, 2.0)
]

# Create SMLD object
smld = BasicSMLD(emitters, cam, 1, 1, Dict{String,Any}())

# Filter operations
roi = filter_roi(smld, 0.0:2.0, 1.0:3.0)
bright = @filter(smld, photons > 1000)

API Overview

For a comprehensive overview of the API, use the help mode on api_overview:

?api_overview

Or access the complete API documentation programmatically:

docs = SMLMData.api_overview()
source
SMLMData.AbstractCameraType
AbstractCamera

Abstract base type for all camera implementations in single molecule localization microscopy (SMLM).

Interface Requirements

Any concrete subtype of AbstractCamera must provide:

  1. Field Requirements:

    • pixel_edges_x::Vector{<:Real}: Vector of pixel edge positions in x direction
    • pixel_edges_y::Vector{<:Real}: Vector of pixel edge positions in y direction
  2. Units:

    • All edge positions must be in physical units (microns)
    • Origin (0,0) corresponds to the top-left corner of the camera
    • For a camera with N×M pixels, there will be N+1 x-edges and M+1 y-edges
  3. Coordinate Convention:

    • Pixel (1,1) is centered at (pixelsizex/2, pixelsizey/2) microns
    • Edge positions define the boundaries of pixels in physical space
    • First edge position corresponds to the left/top edge of the first pixel
    • Last edge position corresponds to the right/bottom edge of the last pixel

Notes

  • Edge positions must be monotonically increasing
  • The number of edges must be one more than the number of pixels in each dimension
  • While pixels are typically uniform in size, this is not a requirement of the interface
source
SMLMData.AbstractEmitterType
AbstractEmitter

Abstract supertype for all emitter types in single molecule localization microscopy (SMLM). All spatial coordinates are specified in physical units (microns).

source
SMLMData.BasicSMLDType
BasicSMLD{T,E<:AbstractEmitter} <: SMLD

Basic container for single molecule localization data.

Fields

  • emitters::Vector{E}: Vector of localized emitters
  • camera::AbstractCamera: Camera used for acquisition
  • n_frames::Int: Total number of frames in acquisition
  • n_datasets::Int: Number of datasets in the acquisition
  • metadata::Dict{String,Any}: Additional dataset information

Type Parameters

  • T: Numeric type for coordinates (typically Float64)
  • E: Concrete emitter type

Example

# Create camera
cam = IdealCamera(1:512, 1:512, 0.1)

# Create some emitters
emitters = [
    Emitter2DFit{Float64}(1.0, 1.0, 1000.0, 10.0, 0.01, 0.01, 50.0, 2.0; frame=1),
    Emitter2DFit{Float64}(5.0, 5.0, 1200.0, 12.0, 0.01, 0.01, 60.0, 2.0; frame=2)
]

# Create metadata
metadata = Dict{String,Any}(
    "exposure_time" => 0.1,
    "timestamp" => now(),
    "sample" => "Test Sample"
)

# Create SMLD object
data = BasicSMLD(emitters, cam, 2, 1, metadata)
source
SMLMData.BasicSMLDMethod
BasicSMLD(emitters::Vector{E}, camera::AbstractCamera,
          n_frames::Int, n_datasets::Int,
          metadata::Dict{String,Any}=Dict{String,Any}()) where E<:AbstractEmitter

Construct a BasicSMLD from a vector of emitters and required metadata.

Arguments

  • emitters::Vector{E}: Vector of localized emitters
  • camera::AbstractCamera: Camera used for acquisition
  • n_frames::Int: Total number of frames in acquisition
  • n_datasets::Int: Number of datasets in acquisition
  • metadata::Dict{String,Any}=Dict{String,Any}(): Optional additional information

The numeric type T is inferred from the camera's pixeledgesx type.

Example

# Create with minimal metadata
data = BasicSMLD(emitters, camera, 10, 1)

# Create with additional metadata
data = BasicSMLD(emitters, camera, 10, 1, Dict(
    "exposure_time" => 0.1,
    "timestamp" => now()
))
source
SMLMData.Emitter2DType
Emitter2D{T} <: AbstractEmitter

Represents a 2D emitter for SMLM simulations with position and brightness.

Fields

  • x::T: x-coordinate in microns
  • y::T: y-coordinate in microns
  • photons::T: number of photons emitted by the fluorophore
source
SMLMData.Emitter2DFitType
Emitter2DFit{T} <: AbstractEmitter

Represents fitted 2D localization results with uncertainties and temporal/tracking information.

Fields

  • x::T: fitted x-coordinate in microns
  • y::T: fitted y-coordinate in microns
  • photons::T: fitted number of photons
  • bg::T: fitted background in photons/pixel
  • σ_x::T: uncertainty in x position in microns
  • σ_y::T: uncertainty in y position in microns
  • σ_photons::T: uncertainty in photon count
  • σ_bg::T: uncertainty in background in photons/pixel
  • frame::Int: frame number in acquisition sequence
  • dataset::Int: identifier for specific acquisition/dataset
  • track_id::Int: identifier for linking localizations across frames (0 = unlinked)
  • id::Int: unique identifier within dataset
source
SMLMData.Emitter2DFitMethod
Emitter2DFit{T}(x, y, photons, bg, σ_x, σ_y, σ_photons, σ_bg;
                frame=0, dataset=1, track_id=0, id=0) where T

Convenience constructor for 2D localization fit results with optional identification parameters.

Arguments

Required

  • x::T: fitted x-coordinate in microns
  • y::T: fitted y-coordinate in microns
  • photons::T: fitted number of photons
  • bg::T: fitted background in photons/pixel
  • σ_x::T: uncertainty in x position in microns
  • σ_y::T: uncertainty in y position in microns
  • σ_photons::T: uncertainty in photon count
  • σ_bg::T: uncertainty in background level

Optional Keywords

  • frame::Int=1: frame number in acquisition sequence
  • dataset::Int=1: identifier for specific acquisition/dataset
  • track_id::Int=0: identifier for linking localizations across frames
  • id::Int=0: unique identifier within dataset

Example

# Create emitter with just required parameters
emitter = Emitter2DFit{Float64}(
    1.0, 2.0,        # x, y
    1000.0, 10.0,    # photons, background
    0.01, 0.01,      # σ_x, σ_y
    50.0, 2.0        # σ_photons, σ_bg
)

# Create emitter with specific frame and dataset
emitter = Emitter2DFit{Float64}(
    1.0, 2.0, 1000.0, 10.0, 0.01, 0.01, 50.0, 2.0;
    frame=5, dataset=2
)
source
SMLMData.Emitter3DType
Emitter3D{T} <: AbstractEmitter

Represents a 3D emitter for SMLM simulations with position and brightness.

Fields

  • x::T: x-coordinate in microns
  • y::T: y-coordinate in microns
  • z::T: z-coordinate in microns (axial position)
  • photons::T: number of photons emitted by the fluorophore
source
SMLMData.Emitter3DFitType
Emitter3DFit{T} <: AbstractEmitter

Represents fitted 3D localization results with uncertainties and temporal/tracking information.

Fields

  • x::T: fitted x-coordinate in microns
  • y::T: fitted y-coordinate in microns
  • z::T: fitted z-coordinate in microns
  • photons::T: fitted number of photons
  • bg::T: fitted background in photons/pixel
  • σ_x::T: uncertainty in x position in microns
  • σ_y::T: uncertainty in y position in microns
  • σ_z::T: uncertainty in z position in microns
  • σ_photons::T: uncertainty in photon count
  • σ_bg::T: uncertainty in background in photons/pixel
  • frame::Int: frame number in acquisition sequence
  • dataset::Int: identifier for specific acquisition/dataset
  • track_id::Int: identifier for linking localizations across frames (0 = unlinked)
  • id::Int: unique identifier within dataset
source
SMLMData.Emitter3DFitMethod
Emitter3DFit{T}(x, y, z, photons, bg, σ_x, σ_y, σ_z, σ_photons, σ_bg;
                frame=0, dataset=1, track_id=0, id=0) where T

Convenience constructor for 3D localization fit results with optional identification parameters.

Arguments

Required

  • x::T: fitted x-coordinate in microns
  • y::T: fitted y-coordinate in microns
  • z::T: fitted z-coordinate in microns
  • photons::T: fitted number of photons
  • bg::T: fitted background in photons/pixel
  • σ_x::T: uncertainty in x position in microns
  • σ_y::T: uncertainty in y position in microns
  • σ_z::T: uncertainty in z position in microns
  • σ_photons::T: uncertainty in photon count
  • σ_bg::T: uncertainty in background level

Optional Keywords

  • frame::Int=1: frame number in acquisition sequence
  • dataset::Int=1: identifier for specific acquisition/dataset
  • track_id::Int=0: identifier for linking localizations across frames
  • id::Int=0: unique identifier within dataset

Example

# Create emitter with just required parameters
emitter = Emitter3DFit{Float64}(
    1.0, 2.0, -0.5,  # x, y, z
    1000.0, 10.0,    # photons, background
    0.01, 0.01, 0.02,# σ_x, σ_y, σ_z
    50.0, 2.0        # σ_photons, σ_bg
)

# Create emitter with specific frame and tracking
emitter = Emitter3DFit{Float64}(
    1.0, 2.0, -0.5, 1000.0, 10.0, 0.01, 0.01, 0.02, 50.0, 2.0;
    frame=5, track_id=1
)
source
SMLMData.IdealCameraType
IdealCamera{T} <: AbstractCamera

Represents an ideal camera with regularly spaced pixels defined by their edges in physical units (microns).

Fields

  • pixel_edges_x::Vector{T}: Physical positions of pixel edges in x direction (microns)
  • pixel_edges_y::Vector{T}: Physical positions of pixel edges in y direction (microns)

The edges are computed from pixel centers, where pixel (1,1) is centered at (pixelsizex/2, pixelsizey/2) in physical coordinates.

source
SMLMData.IdealCameraMethod
IdealCamera(pixel_centers_x::AbstractUnitRange, pixel_centers_y::AbstractUnitRange, 
            pixel_size::Tuple{T, T}) where T<:Real

Construct an IdealCamera with rectangular pixels given pixel center positions and x,y pixel sizes.

Arguments

  • pixel_centers_x::AbstractUnitRange: Range of pixel center indices in x (typically 1:N)
  • pixel_centers_y::AbstractUnitRange: Range of pixel center indices in y (typically 1:M)
  • pixel_size::Tuple{T, T}: Tuple of (xsize, ysize) in microns

Returns

IdealCamera{T} where T matches the type of the pixel sizes

Type Parameters

  • T: Numeric type for all spatial measurements (e.g., Float64, Float32)

Example

# Create a 512x256 camera with rectangular pixels (0.1 x 0.15 microns)
cam = IdealCamera(1:512, 1:256, (0.1, 0.15))

# Create with Float32 precision
cam32 = IdealCamera(1:512, 1:256, (0.1f0, 0.15f0))

Note: Pixel (1,1) is centered at (pixelsize[1]/2, pixelsize[2]/2) in physical coordinates.

source
SMLMData.IdealCameraMethod
IdealCamera(pixel_centers_x::AbstractUnitRange, pixel_centers_y::AbstractUnitRange, pixel_size::T) where T<:Real

Construct an IdealCamera with square pixels given pixel center positions and a scalar pixel size.

Arguments

  • pixel_centers_x::AbstractUnitRange: Range of pixel center indices in x (typically 1:N)
  • pixel_centers_y::AbstractUnitRange: Range of pixel center indices in y (typically 1:M)
  • pixel_size::Real: Size of pixels in microns

Returns

IdealCamera{T} where T matches the type of pixel_size

Type Parameters

  • T: Numeric type for all spatial measurements (e.g., Float64, Float32)

Example

# Create a 512x512 camera with 0.1 micron square pixels
cam = IdealCamera(1:512, 1:512, 0.1)

# Create with Float32 precision
cam32 = IdealCamera(1:512, 1:512, 0.1f0)

Note: Pixel (1,1) is centered at (pixelsize/2, pixelsize/2) in physical coordinates.

source
SMLMData.IdealCameraMethod
IdealCamera(n_pixels_x::Integer, n_pixels_y::Integer, pixel_size::Tuple{T, T}) where T<:Real

Construct an IdealCamera with rectangular pixels directly from the number of pixels and x,y pixel sizes.

Arguments

  • n_pixels_x::Integer: Number of pixels in x dimension
  • n_pixels_y::Integer: Number of pixels in y dimension
  • pixel_size::Tuple{T, T}: Tuple of (xsize, ysize) in microns

Returns

IdealCamera{T} where T matches the type of the pixel sizes

Example

# Create a 512x256 camera with rectangular pixels (0.1 x 0.15 microns)
cam = IdealCamera(512, 256, (0.1, 0.15))

# Create with Float32 precision
cam32 = IdealCamera(512, 256, (0.1f0, 0.15f0))
source
SMLMData.IdealCameraMethod
IdealCamera(n_pixels_x::Integer, n_pixels_y::Integer, pixel_size::T) where T<:Real

Construct an IdealCamera with square pixels directly from the number of pixels and pixel size.

Arguments

  • n_pixels_x::Integer: Number of pixels in x dimension
  • n_pixels_y::Integer: Number of pixels in y dimension
  • pixel_size::Real: Size of pixels in microns

Returns

IdealCamera{T} where T matches the type of pixel_size

Example

# Create a 512x512 camera with 0.1 micron square pixels
cam = IdealCamera(512, 512, 0.1)

# Create with Float32 precision
cam32 = IdealCamera(512, 512, 0.1f0)
source
SMLMData.SMLDType
SMLD

Abstract type representing Single Molecule Localization Data (SMLD).

Interface Requirements

Any concrete subtype of SMLD must provide:

  • emitters::Vector{<:AbstractEmitter}: Vector of localized emitters

Additional fields may include:

  • Camera information
  • Acquisition parameters
  • Analysis metadata

Note: All emitter coordinates must be in physical units (microns).

source
SMLMData.SmiteSMDType
SmiteSMD

Helper structure for loading Smite SMD .mat files.

Fields

  • filepath::String: Path to the directory containing the .mat file
  • filename::String: Name of the .mat file
  • varname::String: Variable name in the .mat file (default: "SMD")

Example

# Load from default "SMD" variable
smd = SmiteSMD("path/to/data", "localizations.mat")

# Load from custom variable name
smd = SmiteSMD("path/to/data", "localizations.mat", "CustomSMD")
source
SMLMData.SmiteSMLDType
SmiteSMLD{T,E<:AbstractEmitter} <: SMLD

SMLD type compatible with the Smite SMD (Single Molecule Data) format.

Fields

  • emitters::Vector{E}: Vector of localized emitters
  • camera::AbstractCamera: Camera used for acquisition
  • n_frames::Int: Total number of frames in acquisition
  • n_datasets::Int: Number of datasets in the acquisition
  • metadata::Dict{String,Any}: Additional dataset information

Type Parameters

  • T: Numeric type for coordinates (typically Float64)
  • E: Concrete emitter type (typically Emitter2DFit or Emitter3DFit)
source
Base.iterateMethod
Base.iterate(smld::SMLD)
Base.iterate(smld::SMLD, state)

Enable iteration over emitters in an SMLD object.

source
Base.lengthMethod
Base.length(smld::SMLD)

Return the number of emitters in the SMLD object.

source
SMLMData.api_overviewMethod

SMLMData.jl API Overview

This guide provides a structured overview of the SMLMData.jl package designed for Single Molecule Localization Microscopy (SMLM) data handling in Julia.

Why This Overview Exists

For Humans

  • Provides a concise reference without diving into full documentation
  • Offers quick-start examples for common use cases
  • Shows relevant patterns more clearly than individual docstrings
  • Creates an at-a-glance understanding of package capabilities

For AI Assistants

  • Enables better code generation with correct API patterns
  • Provides structured context about type hierarchies and relationships
  • Offers consistent examples to learn from when generating code
  • Helps avoid common pitfalls or misunderstandings about the API

Key Concepts

  • Emitters: Individual fluorophore localizations (2D or 3D)
  • Camera: Defines pixel geometry and coordinate system
  • SMLD: Container holding emitters and camera information
  • Coordinates: All spatial coordinates are in microns
  • Coordinate System:
    • Physical space: (0,0) at top-left corner of camera
    • Pixel space: (1,1) at center of top-left pixel

Type Hierarchy

AbstractEmitter                   # Base for all emitter types
├── Emitter2D{T}                  # Basic 2D emitters
├── Emitter3D{T}                  # Basic 3D emitters  
├── Emitter2DFit{T}               # 2D emitters with fit results
└── Emitter3DFit{T}               # 3D emitters with fit results

AbstractCamera                    # Base for all camera types
└── IdealCamera{T}                # Camera with regular pixel grid

SMLD                              # Base for data containers
├── BasicSMLD{T,E}                # General-purpose container
└── SmiteSMLD{T,E}                # SMITE-compatible container

Essential Types

Emitter Types

# Basic 2D emitter
mutable struct Emitter2D{T} <: AbstractEmitter
    x::T           # x-coordinate in microns
    y::T           # y-coordinate in microns
    photons::T     # number of photons emitted
end

# Basic 3D emitter
mutable struct Emitter3D{T} <: AbstractEmitter
    x::T           # x-coordinate in microns
    y::T           # y-coordinate in microns
    z::T           # z-coordinate in microns
    photons::T     # number of photons emitted
end

# 2D emitter with fit results
mutable struct Emitter2DFit{T} <: AbstractEmitter
    x::T           # fitted x-coordinate in microns
    y::T           # fitted y-coordinate in microns
    photons::T     # fitted number of photons
    bg::T          # fitted background in photons/pixel
    σ_x::T         # uncertainty in x position in microns
    σ_y::T         # uncertainty in y position in microns
    σ_photons::T   # uncertainty in photon count
    σ_bg::T        # uncertainty in background level
    frame::Int     # frame number in acquisition sequence
    dataset::Int   # identifier for specific acquisition/dataset
    track_id::Int  # identifier for linking localizations across frames
    id::Int        # unique identifier within dataset
end

# 3D emitter with fit results
mutable struct Emitter3DFit{T} <: AbstractEmitter
    x::T           # fitted x-coordinate in microns
    y::T           # fitted y-coordinate in microns
    z::T           # fitted z-coordinate in microns
    photons::T     # fitted number of photons
    bg::T          # fitted background in photons/pixel
    σ_x::T         # uncertainty in x position in microns
    σ_y::T         # uncertainty in y position in microns
    σ_z::T         # uncertainty in z position in microns
    σ_photons::T   # uncertainty in photon count
    σ_bg::T        # uncertainty in background level
    frame::Int     # frame number in acquisition sequence
    dataset::Int   # identifier for specific acquisition/dataset
    track_id::Int  # identifier for linking localizations across frames
    id::Int        # unique identifier within dataset
end

Emitter Constructor Examples

# Basic 2D emitter
emitter_2d = Emitter2D{Float64}(
    1.5,      # x-coordinate in microns
    2.3,      # y-coordinate in microns  
    1000.0    # number of photons emitted
)

# Basic 3D emitter
emitter_3d = Emitter3D{Float64}(
    1.5,      # x-coordinate in microns
    2.3,      # y-coordinate in microns
    -0.5,     # z-coordinate in microns (negative = below focal plane)
    1000.0    # number of photons emitted
)

# 2D emitter with fit results using convenience constructor
emitter_2d_fit = Emitter2DFit{Float64}(
    1.5, 2.3,        # x, y coordinates in microns
    1000.0, 10.0,    # photons detected, background photons/pixel
    0.01, 0.01,      # σ_x, σ_y: position uncertainties in microns
    50.0, 2.0;       # σ_photons, σ_bg: photon count uncertainties
    frame=5,         # frame number in acquisition (1-based, default=1)
    dataset=1,       # dataset identifier for multi-acquisition experiments
    track_id=2,      # tracking ID for linked localizations (default=0 = unlinked)
    id=42            # unique identifier within this dataset (default=0)
)

Camera Types

# Camera with uniform pixel grid
struct IdealCamera{T} <: AbstractCamera
    pixel_edges_x::Vector{T}  # pixel edges in x
    pixel_edges_y::Vector{T}  # pixel edges in y
end

Camera Constructor Examples

# Create a camera with 512x512 pixels, each 100nm (0.1μm) in size
# Convenience constructor (most common)
cam = IdealCamera(512, 512, 0.1)

# Explicit constructor using pixel center ranges
cam_explicit = IdealCamera(1:512, 1:512, 0.1)

# For non-square pixels, specify different x and y sizes
cam_rect = IdealCamera(512, 512, (0.1, 0.12))

SMLD Container Types

# Basic SMLD container
struct BasicSMLD{T,E<:AbstractEmitter} <: SMLD
    emitters::Vector{E}        # Vector of emitters
    camera::AbstractCamera     # Camera information
    n_frames::Int              # Total number of frames
    n_datasets::Int            # Number of datasets
    metadata::Dict{String,Any} # Additional information
end

# SMITE format compatible container
struct SmiteSMLD{T,E<:AbstractEmitter} <: SMLD
    emitters::Vector{E}        # Vector of emitters
    camera::AbstractCamera     # Camera information
    n_frames::Int              # Total number of frames
    n_datasets::Int            # Number of datasets
    metadata::Dict{String,Any} # Additional information
end

SMLD Constructor Examples

# Create a vector of emitters
emitters = [
    Emitter2DFit{Float64}(1.0, 2.0, 1000.0, 10.0, 0.01, 0.01, 50.0, 2.0),
    Emitter2DFit{Float64}(3.0, 4.0, 1200.0, 12.0, 0.01, 0.01, 60.0, 2.0)
]

# Create a BasicSMLD
smld = BasicSMLD(emitters, camera, 1, 1, Dict{String,Any}())

# Add metadata
smld_with_metadata = BasicSMLD(
    emitters, 
    camera, 
    10,  # number of frames
    1,   # number of datasets
    Dict{String,Any}(
        "exposure_time" => 0.1,
        "sample" => "Test Sample"
    )
)

Core Functions

Accessing the API Overview

# Get this API overview as a string programmatically
overview_text = api_overview()

Coordinate Conversions

# Convert from pixel to physical coordinates (microns)
x_physical, y_physical = pixel_to_physical(px, py, pixel_size)

# Convert from physical to pixel coordinates
px, py = physical_to_pixel(x, y, pixel_size)

# Convert from physical to pixel indices (integers)
px_idx, py_idx = physical_to_pixel_index(x, y, pixel_size)

# Get physical coordinates of all pixel centers
centers_x, centers_y = get_pixel_centers(camera)

Filtering Operations

# Filter by emitter properties using @filter macro
bright = @filter(smld, photons > 1000)                     # Select bright emitters
precise = @filter(smld, σ_x < 0.02 && σ_y < 0.02)         # Select precisely localized emitters
combined = @filter(smld, photons > 1000 && σ_x < 0.02)     # Combine multiple criteria

# The @filter macro supports any emitter property:
# - Basic: x, y, z (for 3D), photons
# - Fit results: bg, σ_x, σ_y, σ_z, σ_photons, σ_bg
# - Metadata: frame, dataset, track_id, id

# Select frames
frame_5 = filter_frames(smld, 5)                  # Single frame
early_frames = filter_frames(smld, 1:10)          # Range of frames (inclusive)
specific_frames = filter_frames(smld, [1,3,5,7])  # Specific frames (uses Set for efficiency)

# Select region of interest (ROI) - coordinates in microns
# 2D ROI
roi_2d = filter_roi(smld, 1.0:5.0, 2.0:6.0)       # x_range, y_range

# 3D ROI (for 3D emitters only)
roi_3d = filter_roi(smld, 1.0:5.0, 2.0:6.0, -1.0:1.0)  # x, y, z ranges

SMLD Operations

# Concatenate multiple SMLDs
combined = cat_smld(smld1, smld2)
combined = cat_smld([smld1, smld2, smld3])

# Merge with options to adjust frame and dataset numbering
merged = merge_smld(smld1, smld2)
merged = merge_smld([smld1, smld2, smld3])

# Merge with sequential frame numbers
sequential = merge_smld([smld1, smld2, smld3], adjust_frames=true)

# Merge with sequential dataset numbers
sequential_ds = merge_smld([smld1, smld2, smld3], adjust_datasets=true)

I/O Operations

# Import from SMITE format (MATLAB)
smd = SmiteSMD("path/to/data", "localizations.mat")  # Default variable name "SMD"
smd = SmiteSMD("path/to/data", "localizations.mat", "CustomSMD")  # Custom variable name

# Load as 2D or 3D data
smld_2d = load_smite_2d(smd)
smld_3d = load_smite_3d(smd)

# Export to SMITE format (saved as MATLAB v7.3 format)
# Note: requires SmiteSMLD object, not BasicSMLD
smite_smld = SmiteSMLD(smld.emitters, smld.camera, smld.n_frames, smld.n_datasets, smld.metadata)
save_smite(smite_smld, "output/directory", "results.mat")

Note: The SMITE loader automatically handles complex-valued fields by removing emitters with non-zero imaginary components in key fields (X, Y, Z, Photons, background, and uncertainties). Information about removed emitters is stored in the metadata as "removed_complex_emitters" => count.

Working with SMLD Objects

# Get number of emitters
n_emitters = length(smld)

# Iterate over emitters
for emitter in smld
    println("Emitter at ($(emitter.x), $(emitter.y)) with $(emitter.photons) photons")
end

# Display formatted information
show(smld)  # Compact view
show(stdout, MIME("text/plain"), smld)  # Detailed view

Common Workflows

Creating and Working with Emitters

# Create emitters
emitter1 = Emitter2DFit{Float64}(1.0, 2.0, 1000.0, 10.0, 0.01, 0.01, 50.0, 2.0)
emitter2 = Emitter2DFit{Float64}(3.0, 4.0, 1200.0, 12.0, 0.01, 0.01, 60.0, 2.0)

# Create camera
cam = IdealCamera(512, 512, 0.1)  # 512x512 camera with 0.1 micron pixels

# Create SMLD container
emitters = [emitter1, emitter2]
smld = BasicSMLD(emitters, cam, 1, 1, Dict{String,Any}())

Loading and Filtering Data

# Load from SMITE format
smd = SmiteSMD("data_directory", "localizations.mat")
smld = load_smite_2d(smd)

# Filter by quality
good_fits = @filter(smld, σ_x < 0.02 && σ_y < 0.02 && photons > 500)

# Filter by ROI
roi = filter_roi(good_fits, 10.0:20.0, 10.0:20.0)

# Filter by frames
frames_1_10 = filter_frames(roi, 1:10)

Multi-Dataset Analysis

# Load multiple datasets
smd1 = SmiteSMD("experiment1", "data.mat")
smd2 = SmiteSMD("experiment2", "data.mat")
smld1 = load_smite_2d(smd1)
smld2 = load_smite_2d(smd2)

# Filter each dataset
bright1 = @filter(smld1, photons > 1000)
bright2 = @filter(smld2, photons > 1000)

# Merge datasets with sequential frame numbering
merged = merge_smld([bright1, bright2], adjust_frames=true)

# Process the merged dataset
result = @filter(merged, σ_x < 0.02 && σ_y < 0.02)

# Save the results (convert to SmiteSMLD first if needed)
result_smite = SmiteSMLD(result.emitters, result.camera, result.n_frames, result.n_datasets, result.metadata)
save_smite(result_smite, "analysis_results", "merged_filtered.mat")

Complete Example

using SMLMData

# 1. Create a camera with 100nm pixels
# Camera has 512x512 pixels, each 0.1 microns (100nm) in size
cam = IdealCamera(512, 512, 0.1)  # Using convenience constructor  

# 2. Create emitters representing single molecule localizations
emitters = [
    # Emitter at (1.0, 2.0) μm with high precision
    Emitter2DFit{Float64}(1.0, 2.0, 1000.0, 10.0, 0.01, 0.01, 50.0, 2.0),
    
    # Bright emitter at (3.0, 4.0) μm
    Emitter2DFit{Float64}(3.0, 4.0, 1200.0, 12.0, 0.01, 0.01, 60.0, 2.0),
    
    # Dimmer emitter at (5.0, 6.0) μm with lower precision
    Emitter2DFit{Float64}(5.0, 6.0, 800.0, 9.0, 0.03, 0.03, 40.0, 1.5)
]

# 3. Create SMLD container to hold all data
smld = BasicSMLD(
    emitters,                              # Vector of emitters
    cam,                                   # Camera geometry
    1,                                     # Number of frames
    1,                                     # Number of datasets
    Dict{String,Any}("sample" => "Test")   # Metadata
)

# 4. Filter by photons to select bright emitters
bright = @filter(smld, photons > 900)      # Creates new SMLD with filtered emitters

# 5. Select region of interest (ROI)
# Select emitters in rectangular region: x ∈ [0, 4] μm, y ∈ [1, 5] μm
roi = filter_roi(bright, 0.0:4.0, 1.0:5.0)

# 6. Examine the results
println("Original dataset: $(length(smld)) emitters")
println("After filtering by brightness: $(length(bright)) emitters")
println("After ROI selection: $(length(roi)) emitters")

# 7. Access individual emitters
for (i, emitter) in enumerate(roi)
    println("Emitter $i: position=($(emitter.x), $(emitter.y)) μm, photons=$(emitter.photons)")
end

# Output:
# Original dataset: 3 emitters
# After filtering by brightness: 2 emitters
# After ROI selection: 2 emitters
# Emitter 1: position=(1.0, 2.0) μm, photons=1000.0
# Emitter 2: position=(3.0, 4.0) μm, photons=1200.0

Common Pitfalls and Important Notes

Coordinate System

  • Physical coordinates are always in microns, not nanometers or pixels
  • Pixel indices start at 1 (Julia convention), not 0
  • Frame numbers start at 1 (default=1, following Julia's 1-based indexing convention)
  • The origin (0,0) in physical space is at the top-left corner of the camera

Type Stability

  • When creating emitters, ensure all numeric fields use the same type (e.g., all Float64)
  • The BasicSMLD constructor automatically infers type T from the camera's pixel edges
  • Mixing types (e.g., Float32 and Float64) can lead to performance issues

Filtering

  • The @filter macro creates a new SMLD object; it doesn't modify the original
  • Filtering by frames with a vector uses Set internally for O(1) lookup performance
  • Applying a 3D ROI filter to 2D emitters will throw an error

SMITE Format

  • Complex-valued fields in SMITE files are automatically handled by removing affected emitters
  • The loader adds metadata about removed emitters: "removed_complex_emitters" => count
  • SMITE files are saved in MATLAB v7.3 format (HDF5-based)

Memory Considerations

  • Large datasets benefit from using appropriate numeric types (e.g., Float32 vs Float64)
  • The filter_frames function with specific frame lists is optimized for sparse selections
  • Iterating over emitters is memory-efficient (doesn't create intermediate arrays)

Common Mistakes

# WRONG: Using pixel units instead of microns
emitter = Emitter2D{Float64}(100, 200, 1000.0)  # ❌ Likely pixel coordinates

# CORRECT: Using micron coordinates
emitter = Emitter2D{Float64}(10.0, 20.0, 1000.0)  # ✓ Physical coordinates

# WRONG: Modifying original SMLD
bright = @filter(smld, photons > 1000)
# smld is unchanged!

# CORRECT: Working with the filtered result
bright = @filter(smld, photons > 1000)
# Use 'bright' for further analysis

api_overview() returns this documentation as a plain String.

source
SMLMData.cat_smldMethod
cat_smld(smlds::Vector{<:SMLD})
cat_smld(smlds::SMLD...)

Concatenate multiple SMLD objects into a single SMLD.

Arguments

  • smlds: Vector of SMLD objects or multiple SMLD arguments

Returns

New SMLD containing all emitters from inputs

Notes

  • Camera must be identical across all SMLDs
  • n_frames is set to maximum frame number across all inputs
  • n_datasets is set to maximum dataset number across all inputs
  • Metadata from first SMLD is used, with conflicts noted in metadata

Examples

# Concatenate two SMLDs
combined = cat_smld(smld1, smld2)

# Concatenate multiple SMLDs
combined = cat_smld(smld1, smld2, smld3)

# Concatenate vector of SMLDs
combined = cat_smld([smld1, smld2, smld3])
source
SMLMData.check_complex_fieldsMethod
check_complex_fields(s, fields)

Check if any of the given fields in s are complex and have non-zero imaginary components. Returns a tuple with:

  1. Boolean indicating if any fields are complex with non-zero imaginary parts
  2. Dict mapping field names to arrays of indices with non-zero imaginary parts
source
SMLMData.compute_bin_edgesMethod
compute_bin_edges(centers_x::AbstractUnitRange, centers_y::AbstractUnitRange, pixel_size::Tuple{Real, Real})

Compute pixel edges in both dimensions for rectangular pixels.

Arguments

  • centers_x::AbstractUnitRange: Range of pixel center indices in x
  • centers_y::AbstractUnitRange: Range of pixel center indices in y
  • pixel_size::Tuple{Real, Real}: Tuple of (xsize, ysize) in microns

Returns

Tuple{Vector{Float64}, Vector{Float64}}: (edgesx, edgesy) in physical units (microns)

source
SMLMData.compute_bin_edgesMethod
compute_bin_edges(centers_x::AbstractUnitRange, centers_y::AbstractUnitRange, pixel_size::T) where T

Compute pixel edges in both dimensions. Returns vectors with same type as pixel_size.

source
SMLMData.compute_edges_1dMethod
compute_edges_1d(centers::AbstractUnitRange, pixel_size::T) where T<:Real

Compute pixel edges in one dimension. Maintains the numeric type of pixelsize. The first edge starts at 0 and each pixel has width pixelsize.

Arguments

  • centers::AbstractUnitRange: Range of pixel center indices
  • pixel_size::T: Size of pixels in microns

Returns

Vector{T}: Edge positions in physical units (microns), starting at 0

source
SMLMData.filter_framesMethod
filter_frames(smld::SMLD, frame::Integer)
filter_frames(smld::SMLD, frames::Union{AbstractVector,AbstractRange})

Efficiently select emitters from specified frames.

Arguments

  • smld::SMLD: Input SMLD structure
  • frames: Single frame number, vector of frame numbers, or range of frames

Returns

New SMLD containing only emitters from specified frames

Examples

# Single frame
frame_5 = filter_frames(smld, 5)

# Range of frames
early = filter_frames(smld, 1:10)

# Multiple specific frames
selected = filter_frames(smld, [1,3,5,7])
source
SMLMData.filter_roiMethod
filter_roi(smld::SMLD, x_range, y_range)
filter_roi(smld::SMLD, x_range, y_range, z_range)

Efficiently select emitters within a region of interest.

Arguments

  • smld::SMLD: Input SMLD structure
  • x_range: Range or tuple for x coordinates (microns)
  • y_range: Range or tuple for y coordinates (microns)
  • z_range: Optional range or tuple for z coordinates (microns)

Returns

New SMLD containing only emitters within the specified ROI

Examples

# 2D ROI
region = filter_roi(smld, 1.0:5.0, 2.0:6.0)
region = filter_roi(smld, (1.0, 5.0), (2.0, 6.0))

# 3D ROI
volume = filter_roi(smld, 1.0:5.0, 2.0:6.0, -1.0:1.0)
source
SMLMData.get_pixel_centersMethod
get_pixel_centers(cam::AbstractCamera)

Calculate the physical coordinates of all pixel centers for any camera type.

For each dimension, the center positions are computed as the midpoint between consecutive edge positions. This works for both regular (uniform pixel size) and irregular (varying pixel size) cameras.

Arguments

  • cam::AbstractCamera: Any camera type that implements the AbstractCamera interface with pixeledgesx and pixeledgesy fields in physical units (microns)

Returns

Tuple{Vector, Vector}: (centersx, centersy) where each vector contains the physical coordinates (in microns) of pixel centers along that dimension

Example

# For a 512x512 camera with 0.1 micron pixels
cam = IdealCamera(1:512, 1:512, 0.1)
centers_x, centers_y = get_pixel_centers(cam)

# First pixel center should be at (0.05, 0.05) microns
@assert centers_x[1] ≈ 0.05
@assert centers_y[1] ≈ 0.05
source
SMLMData.get_valid_indicesMethod
get_valid_indices(s, complex_indices)

Get indices of elements that don't have complex values with non-zero imaginary parts in any field.

source
SMLMData.has_nonzero_imagMethod
has_nonzero_imag(value)

Check if a value has a non-zero imaginary component. Works for both scalar values and arrays.

source
SMLMData.load_smite_2dMethod
load_smite_2d(smd::SmiteSMD)

Load a 2D Smite SMD .mat file and convert it to SmiteSMLD format. Checks for complex fields and removes emitters with non-zero imaginary components.

Arguments

  • smd::SmiteSMD: SmiteSMD object specifying the file to load

Returns

SmiteSMLD containing 2D localizations

Notes

  • All spatial coordinates are converted to microns
  • If PixelSize is not specified in the file, defaults to 0.1 microns
  • Emitters with non-zero imaginary components will be excluded with a warning
  • Fields are converted from Float32 to Float64 as needed
source
SMLMData.load_smite_3dMethod
load_smite_3d(smd::SmiteSMD)

Load a 3D Smite SMD .mat file and convert it to SmiteSMLD format. Checks for complex fields and removes emitters with non-zero imaginary components.

Arguments

  • smd::SmiteSMD: SmiteSMD object specifying the file to load

Returns

SmiteSMLD containing 3D localizations

Notes

  • All spatial coordinates are converted to microns
  • If PixelSize is not specified in the file, defaults to 0.1 microns
  • Emitters with non-zero imaginary components will be excluded with a warning
  • Fields are converted from Float32 to Float64 as needed
source
SMLMData.merge_smldMethod
merge_smld(smlds::Vector{<:SMLD}; adjust_frames=false, adjust_datasets=false)
merge_smld(smlds::SMLD...; adjust_frames=false, adjust_datasets=false)

Merge multiple SMLD objects with options to adjust frame and dataset numbering.

Arguments

  • smlds: Vector of SMLD objects or multiple SMLD arguments
  • adjust_frames: If true, adjusts frame numbers to be sequential
  • adjust_datasets: If true, adjusts dataset numbers to be sequential

Returns

New SMLD containing all emitters with adjusted numbering if requested

Notes

  • Camera must be identical across all SMLDs
  • When adjust_frames=true, frame numbers are made sequential across all inputs
  • When adjust_datasets=true, dataset numbers are made sequential
  • Metadata includes information about the merge operation

Examples

# Simple merge
merged = merge_smld(smld1, smld2)

# Merge with frame number adjustment
merged = merge_smld(smld1, smld2, adjust_frames=true)

# Merge multiple with both adjustments
merged = merge_smld([smld1, smld2, smld3], 
                   adjust_frames=true, 
                   adjust_datasets=true)
source
SMLMData.physical_to_pixelMethod
physical_to_pixel(x::Real, y::Real, pixel_size::Real)

Convert physical coordinates (in microns) to pixel coordinates.

Arguments

  • x::Real: x coordinate in microns (0,0 is top-left of image)
  • y::Real: y coordinate in microns (0,0 is top-left of image)
  • pixel_size::Real: size of a pixel in microns

Returns

Tuple{Float64, Float64}: (px,py) pixel coordinates where (1,1) is center of top-left pixel

Example

# For a camera with 0.1 micron pixels
px, py = physical_to_pixel(0.05, 0.05, 0.1)  # Point 0.05,0.05 microns from origin
# Returns (1.0, 1.0) - center of first pixel
source
SMLMData.physical_to_pixel_indexMethod
physical_to_pixel_index(x::Real, y::Real, pixel_size::Real)

Convert physical coordinates (in microns) to integer pixel indices. Returns the pixel that contains the given physical coordinate.

Arguments

  • x::Real: x coordinate in microns (0,0 is top-left of image)
  • y::Real: y coordinate in microns (0,0 is top-left of image)
  • pixel_size::Real: size of a pixel in microns

Returns

Tuple{Int, Int}: (px,py) pixel indices where (1,1) is top-left pixel

Example

# For a camera with 0.1 micron pixels
px, py = physical_to_pixel_index(0.05, 0.05, 0.1)  # Point at center of first pixel
# Returns (1, 1)
source
SMLMData.pixel_to_physicalMethod
pixel_to_physical(px::Real, py::Real, pixel_size::T) where T

Convert pixel coordinates to physical coordinates (in microns). Returns coordinates with the same type as pixel_size.

source
SMLMData.save_smiteMethod
save_smite(smld::SmiteSMLD, filepath::String, filename::String)

Save SmiteSMLD data back to SMITE's SMD .mat format.

Arguments

  • smld::SmiteSMLD: SMLD object to save
  • filepath::String: Directory path where to save the file
  • filename::String: Name of the output .mat file

Notes

  • Saves in MATLAB v7.3 format
  • Preserves all metadata fields
source
SMLMData.@filterMacro
@filter(smld, condition)

Filter SMLD emitters using a natural condition syntax. Transforms expressions at compile time into efficient filtering operations.

Examples

# Simple conditions
bright = @filter(smld, photons > 1000)
early = @filter(smld, frame < 10)

# Compound conditions
good_fits = @filter(smld, σ_x < 0.02 && σ_y < 0.02)
roi = @filter(smld, 1.0 <= x <= 5.0 && 1.0 <= y <= 5.0)
source