Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "SMLMData"
uuid = "5488f106-40b8-4660-84c5-84a168990d1b"
authors = ["klidke@unm.edu"]
version = "0.5.1"
version = "0.6.0"

[deps]
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
Expand Down
5 changes: 5 additions & 0 deletions api_overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ mutable struct Emitter2DFit{T} <: AbstractEmitter
bg::T # fitted background in photons/pixel
σ_x::T # uncertainty in x position in microns
σ_y::T # uncertainty in y position in microns
σ_xy::T # covariance between x and y (microns², 0 = axis-aligned)
σ_photons::T # uncertainty in photon count
σ_bg::T # uncertainty in background level
frame::Int # frame number in acquisition sequence
Expand All @@ -105,6 +106,9 @@ mutable struct Emitter3DFit{T} <: AbstractEmitter
σ_x::T # uncertainty in x position in microns
σ_y::T # uncertainty in y position in microns
σ_z::T # uncertainty in z position in microns
σ_xy::T # covariance between x and y (microns², 0 = uncorrelated)
σ_xz::T # covariance between x and z (microns², 0 = uncorrelated)
σ_yz::T # covariance between y and z (microns², 0 = uncorrelated)
σ_photons::T # uncertainty in photon count
σ_bg::T # uncertainty in background level
frame::Int # frame number in acquisition sequence
Expand Down Expand Up @@ -138,6 +142,7 @@ emitter_2d_fit = Emitter2DFit{Float64}(
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
σ_xy=0.005, # covariance (optional, default=0 for axis-aligned uncertainty)
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)
Expand Down
6 changes: 6 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ mutable struct Emitter2DFit{T} <: AbstractEmitter
bg::T # fitted background in photons/pixel
σ_x::T # uncertainty in x position in microns
σ_y::T # uncertainty in y position in microns
σ_xy::T # covariance between x and y (microns², 0 = axis-aligned)
σ_photons::T # uncertainty in photon count
σ_bg::T # uncertainty in background level
frame::Int # frame number in acquisition sequence
Expand All @@ -88,6 +89,9 @@ mutable struct Emitter3DFit{T} <: AbstractEmitter
σ_x::T # uncertainty in x position in microns
σ_y::T # uncertainty in y position in microns
σ_z::T # uncertainty in z position in microns
σ_xy::T # covariance between x and y (microns², 0 = uncorrelated)
σ_xz::T # covariance between x and z (microns², 0 = uncorrelated)
σ_yz::T # covariance between y and z (microns², 0 = uncorrelated)
σ_photons::T # uncertainty in photon count
σ_bg::T # uncertainty in background level
frame::Int # frame number in acquisition sequence
Expand Down Expand Up @@ -118,6 +122,7 @@ emitter_2d_fit = Emitter2DFit{Float64}(
1000.0, 10.0, # photons, background
0.01, 0.01, # σ_x, σ_y (uncertainties in μm)
50.0, 2.0; # σ_photons, σ_bg (uncertainties)
σ_xy=0.005, # covariance (optional, 0 = axis-aligned)
frame=5, # frame number
dataset=1, # dataset identifier
track_id=2, # tracking identifier (0 = unlinked)
Expand All @@ -130,6 +135,7 @@ emitter_3d_fit = Emitter3DFit{Float64}(
1000.0, 10.0, # photons, background
0.01, 0.01, 0.02, # σ_x, σ_y, σ_z (uncertainties in μm)
50.0, 2.0; # σ_photons, σ_bg (uncertainties)
σ_xy=0.005, σ_xz=0.002, σ_yz=0.003, # covariances (optional, 0 = uncorrelated)
frame=5, # frame number
dataset=1, # dataset identifier
track_id=2, # tracking identifier (0 = unlinked)
Expand Down
44 changes: 33 additions & 11 deletions src/types/emitters.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ Represents fitted 2D localization results with uncertainties and temporal/tracki
- `bg::T`: fitted background in photons/pixel
- `σ_x::T`: uncertainty in x position in microns
- `σ_y::T`: uncertainty in y position in microns
- `σ_xy::T`: covariance between x and y uncertainties (microns², 0 = axis-aligned)
- `σ_photons::T`: uncertainty in photon count
- `σ_bg::T`: uncertainty in background in photons/pixel
- `frame::Int`: frame number in acquisition sequence
Expand All @@ -66,6 +67,7 @@ mutable struct Emitter2DFit{T} <: AbstractEmitter
bg::T
σ_x::T
σ_y::T
σ_xy::T
σ_photons::T
σ_bg::T
frame::Int
Expand All @@ -88,6 +90,9 @@ Represents fitted 3D localization results with uncertainties and temporal/tracki
- `σ_x::T`: uncertainty in x position in microns
- `σ_y::T`: uncertainty in y position in microns
- `σ_z::T`: uncertainty in z position in microns
- `σ_xy::T`: covariance between x and y (microns², 0 = uncorrelated)
- `σ_xz::T`: covariance between x and z (microns², 0 = uncorrelated)
- `σ_yz::T`: covariance between y and z (microns², 0 = uncorrelated)
- `σ_photons::T`: uncertainty in photon count
- `σ_bg::T`: uncertainty in background in photons/pixel
- `frame::Int`: frame number in acquisition sequence
Expand All @@ -104,6 +109,9 @@ mutable struct Emitter3DFit{T} <: AbstractEmitter
σ_x::T
σ_y::T
σ_z::T
σ_xy::T
σ_xz::T
σ_yz::T
σ_photons::T
σ_bg::T
frame::Int
Expand All @@ -115,7 +123,7 @@ end

"""
Emitter2DFit{T}(x, y, photons, bg, σ_x, σ_y, σ_photons, σ_bg;
frame=0, dataset=1, track_id=0, id=0) where T
σ_xy=zero(T), frame=1, dataset=1, track_id=0, id=0) where T

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

Expand All @@ -131,6 +139,7 @@ Convenience constructor for 2D localization fit results with optional identifica
- `σ_bg::T`: uncertainty in background level

## Optional Keywords
- `σ_xy::T=0`: covariance between x and y uncertainties (microns², 0 = axis-aligned)
- `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
Expand All @@ -146,23 +155,24 @@ emitter = Emitter2DFit{Float64}(
50.0, 2.0 # σ_photons, σ_bg
)

# Create emitter with specific frame and dataset
# Create emitter with covariance for rotated uncertainty ellipse
emitter = Emitter2DFit{Float64}(
1.0, 2.0, 1000.0, 10.0, 0.01, 0.01, 50.0, 2.0;
frame=5, dataset=2
σ_xy=0.005, frame=5, dataset=2
)
```
"""
function Emitter2DFit{T}(x::T, y::T, photons::T, bg::T,
function Emitter2DFit{T}(x::T, y::T, photons::T, bg::T,
σ_x::T, σ_y::T, σ_photons::T, σ_bg::T;
frame::Int=1, dataset::Int=1, track_id::Int=0, id::Int=0) where T
Emitter2DFit{T}(x, y, photons, bg, σ_x, σ_y, σ_photons, σ_bg,
σ_xy::T=zero(T), frame::Int=1, dataset::Int=1, track_id::Int=0, id::Int=0) where T
Emitter2DFit{T}(x, y, photons, bg, σ_x, σ_y, σ_xy, σ_photons, σ_bg,
frame, dataset, track_id, id)
end

"""
Emitter3DFit{T}(x, y, z, photons, bg, σ_x, σ_y, σ_z, σ_photons, σ_bg;
frame=0, dataset=1, track_id=0, id=0) where T
σ_xy=zero(T), σ_xz=zero(T), σ_yz=zero(T),
frame=1, dataset=1, track_id=0, id=0) where T

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

Expand All @@ -180,6 +190,9 @@ Convenience constructor for 3D localization fit results with optional identifica
- `σ_bg::T`: uncertainty in background level

## Optional Keywords
- `σ_xy::T=0`: covariance between x and y (microns², 0 = uncorrelated)
- `σ_xz::T=0`: covariance between x and z (microns², 0 = uncorrelated)
- `σ_yz::T=0`: covariance between y and z (microns², 0 = uncorrelated)
- `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
Expand All @@ -195,17 +208,18 @@ emitter = Emitter3DFit{Float64}(
50.0, 2.0 # σ_photons, σ_bg
)

# Create emitter with specific frame and tracking
# Create emitter with full 3D covariance
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
σ_xy=0.005, σ_xz=0.002, σ_yz=0.003, frame=5, track_id=1
)
```
"""
function Emitter3DFit{T}(x::T, y::T, z::T, photons::T, bg::T,
function Emitter3DFit{T}(x::T, y::T, z::T, photons::T, bg::T,
σ_x::T, σ_y::T, σ_z::T, σ_photons::T, σ_bg::T;
σ_xy::T=zero(T), σ_xz::T=zero(T), σ_yz::T=zero(T),
frame::Int=1, dataset::Int=1, track_id::Int=0, id::Int=0) where T
Emitter3DFit{T}(x, y, z, photons, bg, σ_x, σ_y, σ_z, σ_photons, σ_bg,
Emitter3DFit{T}(x, y, z, photons, bg, σ_x, σ_y, σ_z, σ_xy, σ_xz, σ_yz, σ_photons, σ_bg,
frame, dataset, track_id, id)
end

Expand Down Expand Up @@ -263,6 +277,7 @@ function Base.show(io::IO, ::MIME"text/plain", e::Emitter2DFit{T}) where T
println(io, " Uncertainties:")
println(io, " σ_x: $(e.σ_x) μm")
println(io, " σ_y: $(e.σ_y) μm")
e.σ_xy != 0 && println(io, " σ_xy: $(e.σ_xy) μm²")
println(io, " σ_photons: $(e.σ_photons)")
println(io, " σ_bg: $(e.σ_bg)")
println(io, " Frame: $(e.frame)")
Expand All @@ -289,6 +304,13 @@ function Base.show(io::IO, ::MIME"text/plain", e::Emitter3DFit{T}) where T
println(io, " σ_x: $(e.σ_x) μm")
println(io, " σ_y: $(e.σ_y) μm")
println(io, " σ_z: $(e.σ_z) μm")
has_cov = e.σ_xy != 0 || e.σ_xz != 0 || e.σ_yz != 0
if has_cov
println(io, " Covariances:")
e.σ_xy != 0 && println(io, " σ_xy: $(e.σ_xy) μm²")
e.σ_xz != 0 && println(io, " σ_xz: $(e.σ_xz) μm²")
e.σ_yz != 0 && println(io, " σ_yz: $(e.σ_yz) μm²")
end
println(io, " σ_photons: $(e.σ_photons)")
println(io, " σ_bg: $(e.σ_bg)")
println(io, " Frame: $(e.frame)")
Expand Down
50 changes: 39 additions & 11 deletions test/test_emitters.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,55 +27,83 @@ end
1.0, 2.0, # x, y
1000.0, 10.0, # photons, bg
0.01, 0.01, # σ_x, σ_y
0.005, # σ_xy (covariance)
50.0, 2.0, # σ_photons, σ_bg
1, 1, 0, 1 # frame, dataset, track_id, id
)
@test e2df.x == 1.0
@test e2df.σ_x == 0.01
@test e2df.σ_xy == 0.005
@test e2df.frame == 1
@test e2df.track_id == 0
# Test convenience constructor

# Test convenience constructor (σ_xy defaults to 0)
e2df_simple = Emitter2DFit{Float64}(
1.0, 2.0, 1000.0, 10.0, 0.01, 0.01, 50.0, 2.0
)
@test e2df_simple.frame == 1 # default value
@test e2df_simple.dataset == 1 # default value
@test e2df_simple.track_id == 0 # default value
@test e2df_simple.id == 0 # default value
@test e2df_simple.σ_xy == 0.0 # default covariance

# Test convenience constructor with σ_xy
e2df_cov = Emitter2DFit{Float64}(
1.0, 2.0, 1000.0, 10.0, 0.01, 0.01, 50.0, 2.0;
σ_xy=0.003
)
@test e2df_cov.σ_xy == 0.003
end

@testset "3D Fit" begin
# Test full constructor
e3df = Emitter3DFit{Float64}(
1.0, 2.0, 3.0, # x, y, z
1000.0, 10.0, # photons, bg
0.01, 0.01, 0.02, # σ_x, σ_y, σ_z
50.0, 2.0, # σ_photons, σ_bg
1, 1, 0, 1 # frame, dataset, track_id, id
1.0, 2.0, 3.0, # x, y, z
1000.0, 10.0, # photons, bg
0.01, 0.01, 0.02, # σ_x, σ_y, σ_z
0.005, 0.002, 0.003, # σ_xy, σ_xz, σ_yz (covariances)
50.0, 2.0, # σ_photons, σ_bg
1, 1, 0, 1 # frame, dataset, track_id, id
)
@test e3df.z == 3.0
@test e3df.σ_z == 0.02

# Test convenience constructor
@test e3df.σ_xy == 0.005
@test e3df.σ_xz == 0.002
@test e3df.σ_yz == 0.003

# Test convenience constructor (covariances default to 0)
e3df_simple = Emitter3DFit{Float64}(
1.0, 2.0, 3.0, 1000.0, 10.0,
1.0, 2.0, 3.0, 1000.0, 10.0,
0.01, 0.01, 0.02, 50.0, 2.0
)
@test e3df_simple.frame == 1
@test e3df_simple.dataset == 1
@test e3df_simple.σ_xy == 0.0
@test e3df_simple.σ_xz == 0.0
@test e3df_simple.σ_yz == 0.0

# Test convenience constructor with full 3D covariance
e3df_cov = Emitter3DFit{Float64}(
1.0, 2.0, 3.0, 1000.0, 10.0,
0.01, 0.01, 0.02, 50.0, 2.0;
σ_xy=0.003, σ_xz=0.001, σ_yz=0.002
)
@test e3df_cov.σ_xy == 0.003
@test e3df_cov.σ_xz == 0.001
@test e3df_cov.σ_yz == 0.002
end
end

@testset "Type Stability" begin
# Test that operations maintain type stability
e2d = Emitter2D{Float64}(1.0, 2.0, 1000.0)
@test typeof(e2d.x) === Float64

e2df = Emitter2DFit{Float32}(
1.0f0, 2.0f0, 1000.0f0, 10.0f0,
0.01f0, 0.01f0, 50.0f0, 2.0f0
)
@test typeof(e2df.x) === Float32
@test typeof(e2df.σ_x) === Float32
@test typeof(e2df.σ_xy) === Float32
end