soft-matter / trackpy

Python particle tracking toolkit
http://soft-matter.github.io/trackpy
Other
437 stars 131 forks source link

[Question] methods for initial estimation of `minmass` #761

Open jacopoabramo opened 2 months ago

jacopoabramo commented 2 months ago

I'm currently using trackpy for tracking particles over 3D. For various reasons I'm not using 3D feature finding but instead I'm scanning a volume over z and finding centroids in 2D. Then I do some other processing to obtain the estimation over z with a different method. I cannot unfortunately go into details on this matter at this time, but for the purpose of my question is not relevant.

I would like to perform an initial estimation of the minimum value of minmass that I would need to identify a target number of particles in my images. At this time I'm doing something on these lines:

Helper function:

def introspect_volume(volume: np.ndarray, diameter: int, **locate) -> int:
    """ Introspect the volume to determine how many particles are present
    with the input value of `minmass`.

    Args:
        volume (`np.ndarray`): input 3D volume, with shape (z, y, x);
        diameter (`int`): diameter of the particles to locate in pixels;
        locate (`dict`): kwargs for the `trackpy.locate` function.

    Returns:
        `int`: maximum number of particles found in the introspection.
    """
    return np.max([
        len(tp.locate(volume[frame], diameter=diameter, **locate))
        for frame in range(len(volume))
    ]) # particles per frame

Actual estimation:

# we set the 'minmass' parameter to 0 to detect all particles
locate['minmass'] = 0

# we select a volume to analyze
selected_volume = volumes[0]

# introspect the volume to find a suitable 'minmass' value;
# we set as target the number of particles to be detected
# and the minimum increase step of 'minmass' to reach the target
target = 1
minmass_step = 0.05

# current number of found particles,
# initialized to infinity
current = np.infty

pbar = tqdm(total=100)
pbar.desc = f"minmass: {locate['minmass']}, detected: {current}"

# we iterate until we reach the target number of particles
with warnings.catch_warnings():
    warnings.simplefilter("ignore", UserWarning)
    while current > target:
        current = introspect_volume(volumes[0], diameter, **locate)
        locate['minmass'] = round(locate['minmass'] + minmass_step, 2)
        pbar.update()
        pbar.desc = f"minmass: {locate['minmass']}, detected: {current}"
print(f"Final minmass value: {locate['minmass']}")

I understand that trackpy currently offers a variety of other APIs that I could use for a (possibly) more accurate and more efficient approach to this problem, i.e. using somehow grey_dilation together with other APIs to obtain an initial estimation.

Currently I'm content with this approach but any insight in other possibilities would be appreciated.

b-grimaud commented 2 months ago

I typically do the same, albeit by plotting the number of features found for each minmass and then setting a threshold. Jupyter widgets can also offer a convenient way to interactively play with each parameter and see the results.