Skip to content

Commit fba0dc7

Browse files
restructure examples
1 parent 9842bb3 commit fba0dc7

File tree

81 files changed

+8387
-4012
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+8387
-4012
lines changed

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,9 @@ dist/*
99
*.egg-info/
1010
*/datasets/*
1111
*/theory
12-
_src/build/**/*
12+
_src/build/**/*
13+
14+
ParticleSizing
15+
3DTracking
16+
CellData
17+
ParticleTracking

autotrack-examples/train_label_free_multiparticle_tracker.ipynb

Lines changed: 0 additions & 426 deletions
This file was deleted.

autotrack-examples/train_label_free_particle_orientation.ipynb

Lines changed: 0 additions & 374 deletions
This file was deleted.

autotrack-examples/train_label_free_particle_tracker_experimental_data.ipynb

Lines changed: 0 additions & 498 deletions
This file was deleted.

deeptrack/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from .sequences import *
2727
from .elementwise import *
2828
from .statistics import *
29+
from .holography import *
2930

3031
from .image import strip
3132

deeptrack/extras/datasets.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"MitoGAN",
4343
"1Qf5vIWEksKPHJ1CBK6GPEhsSCvFFHFrg",
4444
),
45+
"CellData": ("1CJW7msDiI7xq7oMce4l9tRkNN6O5eKtj", "CellData", ""),
4546
}
4647

4748

deeptrack/features.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ def action(self, replicate_index=None):
191191
# Get the input arguments to the method .get()
192192

193193
feature_input = self.properties(replicate_index=replicate_index).copy()
194-
194+
195195
# Call the _process_properties hook, default does nothing.
196196
# Can be used to ensure properties are formatted correctly
197197
# or to rescale properties.
@@ -232,7 +232,7 @@ def action(self, replicate_index=None):
232232
def __call__(
233233
self, image_list: Image or List[Image] = None, replicate_index=None, **kwargs
234234
):
235-
235+
236236
# Potentially fragile. Maybe a special variable dt._last_input instead?
237237
if image_list is not None and not (
238238
isinstance(image_list, list) and len(image_list) == 0
@@ -352,7 +352,7 @@ def plot(
352352
if isinstance(output_image, Image):
353353
# Single image
354354
plt.imshow(output_image[:, :, 0], **kwargs)
355-
plt.show()
355+
return plt.gca()
356356

357357
else:
358358
# Assume video

deeptrack/holography.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
from .features import Feature
2+
import numpy as np
3+
4+
5+
def get_propagation_matrix(shape, to_z, pixel_size, wavelength):
6+
7+
k = 2 * np.pi / wavelength
8+
yr, xr, *_ = shape
9+
10+
x = 2 * np.pi / pixel_size * np.arange(-(xr / 2 - 1 / 2), (xr / 2 + 1 / 2), 1) / xr
11+
y = 2 * np.pi / pixel_size * np.arange(-(yr / 2 - 1 / 2), (yr / 2 + 1 / 2), 1) / yr
12+
KXk, KYk = np.meshgrid(x, y)
13+
14+
K = np.real(
15+
np.sqrt(np.array(1 - (KXk / k) ** 2 - (KYk / k) ** 2, dtype=np.complex64))
16+
)
17+
C = np.fft.fftshift(((KXk / k) ** 2 + (KYk / k) ** 2 < 1) * 1.0)
18+
19+
return C * np.fft.fftshift(np.exp(k * 1j * to_z * (K - 1)))
20+
21+
22+
class Rescale(Feature):
23+
"""Rescales an optical field by subtracting the real part of the field beofre multiplication.
24+
25+
Parameters
26+
----------
27+
rescale : float
28+
index of z-propagator matrix
29+
"""
30+
31+
def __init__(self, rescale=1, **kwargs):
32+
super().__init__(rescale=rescale, **kwargs)
33+
34+
def get(self, image, rescale, **kwargs):
35+
image = np.array(image)
36+
image[..., 0] = (image[..., 0] - 1) * rescale + 1
37+
image[..., 1] *= rescale
38+
39+
return image
40+
41+
42+
class FourierTransform(Feature):
43+
"""Creates matrices for propagating an optical field.
44+
45+
Parameters
46+
----------
47+
i : int
48+
index of z-propagator matrix
49+
"""
50+
51+
def __init__(self, **kwargs):
52+
super().__init__(**kwargs)
53+
54+
def get(self, image, padding=32, **kwargs):
55+
56+
im = np.copy(image[..., 0] + 1j * image[..., 1])
57+
im = np.pad(im, ((padding, padding), (padding, padding)), mode="symmetric")
58+
f1 = np.fft.fft2(im)
59+
return f1
60+
61+
62+
class InverseFourierTransform(Feature):
63+
"""Creates matrices for propagating an optical field.
64+
65+
Parameters
66+
----------
67+
i : int
68+
index of z-propagator matrix
69+
"""
70+
71+
def __init__(self, **kwargs):
72+
super().__init__(**kwargs)
73+
74+
def get(self, image, padding=32, **kwargs):
75+
im = np.fft.ifft2(image)
76+
imnew = np.zeros(
77+
(image.shape[0] - padding * 2, image.shape[1] - padding * 2, 2)
78+
)
79+
imnew[..., 0] = np.real(im[padding:-padding, padding:-padding])
80+
imnew[..., 1] = np.imag(im[padding:-padding, padding:-padding])
81+
return imnew
82+
83+
84+
class FourierTransformTransformation(Feature):
85+
def __init__(self, Tz, Tzinv, i, **kwargs):
86+
super().__init__(Tz=Tz, Tzinv=Tzinv, i=i, **kwargs)
87+
88+
def get(self, image, Tz, Tzinv, i, **kwargs):
89+
if i < 0:
90+
image *= Tzinv ** np.abs(i)
91+
else:
92+
image *= Tz ** i
93+
return image

deeptrack/image.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,11 @@ def __getattr__(self, key):
326326

327327
def __getitem__(self, idx):
328328
idx = strip(idx)
329-
out = Image(self._value.__getitem__(idx), copy=False)
329+
out = self._value.__getitem__(idx)
330+
if isinstance(out, (bool, int, float, complex)):
331+
return out
332+
333+
out = Image(out, copy=False)
330334
out.merge_properties_from([self, idx])
331335
return out
332336

deeptrack/models/autotracking/equivariances.py

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,31 @@
1+
""" User defined equivariances for training autotrackers.
2+
3+
Example:
4+
action = Multiply(value=np.random.uniform(0.5, 1.5))
5+
equivariance = Equivariance(mul=action.value)
6+
7+
"""
8+
19
from ...features import Feature
210
import numpy as np
311

412

513
class Equivariance(Feature):
14+
"""Defines equivariance between action and prediction.
15+
16+
Should define both a multiplicative equivariance (1, if invariant) and a additive equivariance (0, if invariant)
17+
18+
Parameters
19+
----------
20+
mul : float, array-like
21+
Multiplicative equivariance
22+
add : float, array-like
23+
Additive equivariance
24+
indexes : optional, int or slice
25+
Index of related predicted value(s)
26+
27+
"""
28+
629
def __init__(self, mul, add, indexes=slice(None, None, 1), **kwargs):
730
super().__init__(mul=mul, add=add, indexes=indexes, **kwargs)
831

@@ -22,6 +45,15 @@ def get(self, matvec, mul, add, indexes, **kwargs):
2245

2346

2447
class TranslationalEquivariance(Equivariance):
48+
"""Defines translation-like equivariance between action and prediction, for use with dt.Affine
49+
50+
Parameters
51+
----------
52+
translate : float, array-like
53+
Should be exactly `affine.translate`
54+
55+
"""
56+
2557
def __init__(self, translation, indexes=None):
2658
if indexes is None:
2759
indexes = self.get_indexes
@@ -40,25 +72,43 @@ def get_indexes(self, translation):
4072

4173

4274
class Rotational2DEquivariance(Equivariance):
43-
def __init__(self, rotation, indexes=None):
75+
"""Defines rotation-like equivariance between action and prediction, for use with dt.Affine
76+
77+
Parameters
78+
----------
79+
rotate : float, array-like
80+
Should be exactly `affine.rotate`
81+
82+
"""
83+
84+
def __init__(self, rotate, indexes=None):
4485
if indexes is None:
4586
indexes = self.get_indexes
4687
super().__init__(
47-
rotation=rotation, add=self.get_add, mul=self.get_mul, indexes=indexes
88+
rotate=rotate, add=self.get_add, mul=self.get_mul, indexes=indexes
4889
)
4990

5091
def get_add(self):
5192
return np.zeros((2, 1))
5293

53-
def get_mul(self, rotation):
54-
s, c = np.sin(rotation), np.cos(rotation)
94+
def get_mul(self, rotate):
95+
s, c = np.sin(rotate), np.cos(rotate)
5596
return np.array([[c, s], [-s, c]])
5697

5798
def get_indexes(self):
5899
return slice(2)
59100

60101

61102
class ScaleEquivariance(Equivariance):
103+
"""Defines scale-like equivariance between action and prediction, for use with dt.Affine
104+
105+
Parameters
106+
----------
107+
scale : float, array-like
108+
Should be exactly `affine.scale`
109+
110+
"""
111+
62112
def __init__(self, scale, indexes=None):
63113
if indexes is None:
64114
indexes = self.get_indexes
@@ -77,6 +127,17 @@ def get_indexes(self, scale):
77127

78128

79129
class LogScaleEquivariance(Equivariance):
130+
"""Defines scale-like equivariance between action and prediction, for use with dt.Affine
131+
132+
Converts the scaling to log scale, for an additive equivariance.
133+
134+
Parameters
135+
----------
136+
scale : float, array-like
137+
Should be exactly `affine.scale`
138+
139+
"""
140+
80141
def __init__(self, scale, indexes=None):
81142
if indexes is None:
82143
indexes = self.get_indexes

0 commit comments

Comments
 (0)