Tutorial about localization precision#

Localization precision is determined from consecutive localizations that are identified within a certain search radius. The results include the distances between localization pairs, the position deltas for each coordinate and the corresponding frame of the first localizations.

from pathlib import Path

%matplotlib inline

import matplotlib.pyplot as plt

import locan as lc
lc.show_versions(system=False, dependencies=False, verbose=False)
Locan:
   version: 0.20.0.dev41+g755b969

Python:
   version: 3.11.6

Load SMLM data file#

Identify some data in the test_data directory and provide a path using pathlib.Path (returned by lc.ROOT_DIR)

path = lc.ROOT_DIR / 'tests/test_data/npc_gp210.asdf'
print(path, '\n')
dat = lc.load_locdata(path=path, file_type=lc.FileType.ASDF)
/home/docs/checkouts/readthedocs.org/user_builds/locan/envs/latest/lib/python3.11/site-packages/locan/tests/test_data/npc_gp210.asdf 
Jupyter environment detected. Enabling Open3D WebVisualizer.
[Open3D INFO] WebRTC GUI backend enabled.
[Open3D INFO] WebRTCWindowSystem: HTTP handshake server disabled.

Print information about the data:

print(dat.data.head(), '\n')
print('Summary:')
dat.print_summary()
print('Properties:')
print(dat.properties)
    position_x   position_y  frame     intensity  two_kernel_improvement  \
0  5631.709961  6555.850098     24  21800.699219                     0.0   
1  5642.899902  6550.990234     25  23352.900391                     0.0   
2  5610.319824  6546.819824     26   5007.509766                     0.0   
3  5713.299805  6611.950195    141   6437.140137                     0.0   
4  5699.750000  6627.390137    142  19998.300781                     0.0   

   chi_square  local_background  
0   1426930.0       1188.489990  
1    983634.0       1135.199951  
2    577707.0       1107.219971  
3    616255.0       1118.430054  
4    903412.0       1144.709961   

Summary:
identifier: "5"
comment: ""
source: EXPERIMENT
state: MODIFIED
element_count: 202
frame_count: 202
file {
  type: ASDF
  path: "/home/docs/checkouts/readthedocs.org/user_builds/locan/envs/latest/lib/python3.11/site-packages/locan/tests/test_data/npc_gp210.asdf"
}
creation_time {
  2024-01-23T08:32:31.518779Z
}
modification_time {
  2024-01-23T08:32:31.518779Z
}

Properties:
{'localization_count': 202, 'position_x': 5623.488892810179, 'uncertainty_x': 3.9700846636030356, 'position_y': 6625.534602703435, 'uncertainty_y': 3.999303432482808, 'intensity': 3944778.0, 'local_background': 1131.3207, 'frame': 24, 'region_measure_bb': 47134.543, 'localization_density_bb': 0.00428560429946091, 'subregion_measure_bb': 870.98046875}

Visualization#

lc.render_2d(dat, bin_size=10, rescale=(0,100));
../../_images/dbfbe732ad730a83a8aed3b45a618ed47a51ad674a1de9a67b33af14476218f3.png

Analyze localization precision#

lp = lc.LocalizationPrecision(radius=50)
lp.compute(dat)
lp.results.head()
Processed frames::   0%|          | 0/24884 [00:00<?, ?it/s]
Processed frames::   6%|▌         | 1401/24884 [00:00<00:01, 13892.00it/s]
Processed frames::  16%|█▌        | 3906/24884 [00:00<00:01, 20010.85it/s]
Processed frames::  25%|██▌       | 6245/24884 [00:00<00:00, 21481.83it/s]
Processed frames::  36%|███▌      | 8880/24884 [00:00<00:00, 23094.35it/s]
Processed frames::  64%|██████▍   | 15900/24884 [00:00<00:00, 39841.49it/s]
Processed frames::  99%|█████████▉| 24643/24884 [00:00<00:00, 55869.86it/s]
Processed frames:: 100%|██████████| 24884/24884 [00:00<00:00, 40163.68it/s]

position_delta_x position_delta_y position_distance frame
0 -11.189941 4.859863 12.199716 24
1 32.580078 4.170410 32.845909 25
2 13.549805 -15.439941 20.542370 141
3 4.669922 3.010254 5.556060 142
4 20.469727 14.750000 25.230383 239

The plot

lp.plot(loc_property='position_delta_x', window=10);
../../_images/09811bd1cf0601e2d9858f878fbe180e6aa903f7165fd5cf6201c03fac6f0eed.png
lp.plot(window=10);
../../_images/71a9349a2cb7033b1c95a2b1545a4d2a3100237fa5b9691c8f19a0155c0803ab.png

The histogram for the distances per default includes a fit to a distribution expected for normal distributed localizations. Sigma / sqrt(2) is the localization precision.

lp.hist();
../../_images/c298ea8f2fff75a057c004029fb78db9cd090d26dad758b3eef9d4bd426ad1da.png

Alternatively the position deltas can be histogrammed.

fig, ax = plt.subplots(nrows=1, ncols=2)
lp.hist(ax=ax[0], loc_property='position_delta_x')
lp.hist(ax=ax[1], loc_property='position_delta_y')
plt.tight_layout()
plt.show()
../../_images/10f612848d4b46b9b261e5337529079ab11c19f259e0360df46524702f75c9c0.png

Fit distributions and show parameters#

Appropriate distribution functions are fitted to the data either by calling the hist function or by running:

lp.fit_distributions()

The estimated fit parameters are provided under the distribution_statistics attribute

lp.distribution_statistics.parameter_dict()
{'position_delta_x_loc': 0.6029139,
 'position_delta_x_scale': 13.2682,
 'position_delta_y_loc': -1.227687,
 'position_delta_y_scale': 14.76087,
 'position_distance_sigma': 14.067675781250028,
 'position_distance_loc': 0,
 'position_distance_scale': 1}

Remember: localization precision is typically defined as the standard deviation for the distances between localizations and their center position (the true dye position). Therefore, the estimated sigmas have to be divided by sqrt(2) to yield localization precision.