Skip to content

Commit 89aed3e

Browse files
committed
black documentation
1 parent bbf42b1 commit 89aed3e

File tree

5 files changed

+161
-95
lines changed

5 files changed

+161
-95
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,10 @@ pip install -r requirements.txt -r requirements-dev.txt
3030
# Run tests
3131
pytest tests/ -v --benchmark-autosave --cov=simtk
3232
```
33+
34+
This project uses the [black](https://github.com/psf/black) code formatter for
35+
a consistent coding style. To apply the formatter:
36+
37+
```
38+
black simtk/* tests/*
39+
```

simtk/__init__.py

Lines changed: 107 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,20 @@
33
__version__ = "0.1.0"
44

55
__all__ = [
6-
'load_image',
7-
'normalize_psf',
8-
'center_psf',
9-
'generate_otf',
10-
'normalize_otf',
11-
'save_otf',
12-
'load_otf',
13-
]
6+
"load_image",
7+
"normalize_psf",
8+
"center_psf",
9+
"generate_otf",
10+
"normalize_otf",
11+
"save_otf",
12+
"load_otf",
13+
]
1414

1515
import itk
1616
import numpy as np
1717
import scipy.optimize
1818

19+
1920
def load_image(filename, nphases=3, norientations=1, spacing=None):
2021
"""Load SIM acquisition data from an image file.
2122
@@ -48,16 +49,20 @@ def load_image(filename, nphases=3, norientations=1, spacing=None):
4849
data_view = itk.array_view_from_image(image)
4950

5051
size = itk.size(image)
51-
components = nphases*norientations
52+
components = nphases * norientations
5253

5354
result_shape = list(data_view.shape)
5455
result_shape[0] = int(result_shape[0] / components)
55-
result_shape = result_shape + [components,]
56+
result_shape = result_shape + [
57+
components,
58+
]
5659
result = np.empty(result_shape, dtype=np.float32)
5760
for component in range(components):
58-
result[:,:,:,component] = data_view[component::components,:,:]
61+
result[:, :, :, component] = data_view[component::components, :, :]
5962

60-
result = itk.PyBuffer[itk.VectorImage[itk.F, 3]].GetImageViewFromArray(result, is_vector=True)
63+
result = itk.PyBuffer[itk.VectorImage[itk.F, 3]].GetImageViewFromArray(
64+
result, is_vector=True
65+
)
6166
result.SetOrigin(image.GetOrigin())
6267
result.SetSpacing(image.GetSpacing())
6368
result.SetDirection(image.GetDirection())
@@ -66,6 +71,7 @@ def load_image(filename, nphases=3, norientations=1, spacing=None):
6671

6772
return result
6873

74+
6975
def normalize_psf(psf):
7076
"""Remove DC fourier component, normalize information component to sum to
7177
unity.
@@ -92,13 +98,16 @@ def normalize_psf(psf):
9298
sum_ = np.sum(result[..., component])
9399
result[..., component] = result[..., component] / sum_
94100

95-
result_image = itk.PyBuffer[itk.VectorImage[itk.F, 3]].GetImageViewFromArray(result, is_vector=True)
101+
result_image = itk.PyBuffer[itk.VectorImage[itk.F, 3]].GetImageViewFromArray(
102+
result, is_vector=True
103+
)
96104
result_image.SetOrigin(psf.GetOrigin())
97105
result_image.SetSpacing(psf.GetSpacing())
98106
result_image.SetDirection(psf.GetDirection())
99107

100108
return result_image
101109

110+
102111
def center_psf(psf):
103112
"""Center the PSF in the image. The data is resampled around the center and
104113
the origin of the output is set to the center.
@@ -124,44 +133,50 @@ def center_psf(psf):
124133
widefield_psf /= np.sum(widefield_psf)
125134

126135
(nz, ny, nx) = widefield_psf.shape
127-
(zz, yy, xx) = np.meshgrid(np.arange(nz), np.arange(ny), np.arange(nx), indexing='ij')
136+
(zz, yy, xx) = np.meshgrid(
137+
np.arange(nz), np.arange(ny), np.arange(nx), indexing="ij"
138+
)
128139
peak_image_flat = np.ravel(widefield_psf)
129-
peak_data = np.stack((peak_image_flat,
130-
np.ravel(zz),
131-
np.ravel(yy),
132-
np.ravel(xx)),
133-
axis=1)
140+
peak_data = np.stack(
141+
(peak_image_flat, np.ravel(zz), np.ravel(yy), np.ravel(xx)), axis=1
142+
)
134143

135144
max_value = np.max(peak_image_flat)
136145
max_index = np.argmax(peak_image_flat)
137146
(cz, cy, cx) = np.unravel_index(max_index, widefield_psf.shape)
138147

139148
initial_params = np.zeros((7,), dtype=np.float64)
140-
initial_params[0] = max_value # max value in the window
141-
initial_params[1] = cz # z pixel index of the peak
142-
initial_params[2] = cy # y pixel index of the peak
143-
initial_params[3] = cx # x pixel index of the peak
144-
initial_params[4] = 1.5 # z sigma
145-
initial_params[5] = 1.5 # y sigma
146-
initial_params[6] = 1.5 # x sigma
149+
initial_params[0] = max_value # max value in the window
150+
initial_params[1] = cz # z pixel index of the peak
151+
initial_params[2] = cy # y pixel index of the peak
152+
initial_params[3] = cx # x pixel index of the peak
153+
initial_params[4] = 1.5 # z sigma
154+
initial_params[5] = 1.5 # y sigma
155+
initial_params[6] = 1.5 # x sigma
147156

148157
def gaussian_fit_objective(params, peak_data):
149-
actual = peak_data[:,0]
150-
expected = params[0] * np.exp(-((peak_data[:,1] - params[1])**2 / (2*params[4]**2) + \
151-
(peak_data[:,2] - params[2])**2 / (2*params[5]**2) + \
152-
(peak_data[:,3] - params[3])**2 / (2*params[6]**2)))
158+
actual = peak_data[:, 0]
159+
expected = params[0] * np.exp(
160+
-(
161+
(peak_data[:, 1] - params[1]) ** 2 / (2 * params[4] ** 2)
162+
+ (peak_data[:, 2] - params[2]) ** 2 / (2 * params[5] ** 2)
163+
+ (peak_data[:, 3] - params[3]) ** 2 / (2 * params[6] ** 2)
164+
)
165+
)
153166
err = actual - expected
154-
result = np.sum(err**2)
167+
result = np.sum(err ** 2)
155168
return result
156169

157-
params_opt = scipy.optimize.fmin(func=gaussian_fit_objective,
158-
x0=initial_params,
159-
args=(peak_data,),
160-
maxiter=10000,
161-
maxfun=10000,
162-
disp=False,
163-
xtol=1e-6,
164-
ftol=1e-6)
170+
params_opt = scipy.optimize.fmin(
171+
func=gaussian_fit_objective,
172+
x0=initial_params,
173+
args=(peak_data,),
174+
maxiter=10000,
175+
maxfun=10000,
176+
disp=False,
177+
xtol=1e-6,
178+
ftol=1e-6,
179+
)
165180
(cz_opt, cy_opt, cx_opt) = params_opt[1:4]
166181

167182
result = np.copy(psf_arr)
@@ -171,21 +186,25 @@ def gaussian_fit_objective(params, peak_data):
171186
transform_params[1] = float(cy) - cy_opt
172187
transform_params[2] = float(cz) - cz_opt
173188
transform.SetParameters(transform_params)
174-
interpolator = itk.WindowedSincInterpolateImageFunction[itk.Image[itk.F,3],
175-
3, itk.HammingWindowFunction[3]].New()
189+
interpolator = itk.WindowedSincInterpolateImageFunction[
190+
itk.Image[itk.F, 3], 3, itk.HammingWindowFunction[3]
191+
].New()
176192
for component in range(psf_arr.shape[-1]):
177193
component_arr = psf_arr[..., component]
178194
component_image = itk.image_view_from_array(component_arr)
179-
resampled = itk.resample_image_filter(component_image,
180-
use_reference_image=True,
181-
reference_image=component_image,
182-
transform=transform,
183-
interpolator=interpolator,
184-
)
195+
resampled = itk.resample_image_filter(
196+
component_image,
197+
use_reference_image=True,
198+
reference_image=component_image,
199+
transform=transform,
200+
interpolator=interpolator,
201+
)
185202
resampled_arr = itk.array_view_from_image(resampled)
186203
result[..., component] = resampled_arr
187204

188-
result_image = itk.PyBuffer[itk.VectorImage[itk.F, 3]].GetImageViewFromArray(result, is_vector=True)
205+
result_image = itk.PyBuffer[itk.VectorImage[itk.F, 3]].GetImageViewFromArray(
206+
result, is_vector=True
207+
)
189208
origin = list(itk.origin(psf))
190209
spacing = itk.spacing(psf)
191210
origin[0] -= cx * spacing[0]
@@ -197,6 +216,7 @@ def gaussian_fit_objective(params, peak_data):
197216

198217
return result_image
199218

219+
200220
def make_forward_separation_matrix(nphases, norders, lattice_period, phase_step):
201221
"""Generate the forward matrix required to separate OTF orders from an image
202222
acquired under multiple phases of illumination. This matrix will need
@@ -205,25 +225,35 @@ def make_forward_separation_matrix(nphases, norders, lattice_period, phase_step)
205225
"""
206226

207227
# After this step, separation of orders will be [0, +1, -1, +2, -2,...]
208-
delta_phi = phase_step / lattice_period*2*np.pi # Convert phase step in nm to phase step as a fraction of 2pi
228+
delta_phi = (
229+
phase_step / lattice_period * 2 * np.pi
230+
) # Convert phase step in nm to phase step as a fraction of 2pi
209231

210232
sep_matrix = np.zeros((nphases, norders), dtype=np.complex128)
211233
for phase in range(nphases):
212234
counter = 0
213235
phase_sign = 1
214236
for order in range(norders):
215-
sep_matrix[phase, order] = np.exp(1.j*phase_sign*counter*phase*delta_phi)
216-
counter += np.mod(order+1, 2)
217-
phase_sign = -1 + 2*np.mod(order+1, 2)
237+
sep_matrix[phase, order] = np.exp(
238+
1.0j * phase_sign * counter * phase * delta_phi
239+
)
240+
counter += np.mod(order + 1, 2)
241+
phase_sign = -1 + 2 * np.mod(order + 1, 2)
218242

219243
# Reorganize so that orders will be [..-2,-1,0,+1,+2...]
220244
sep_matrix_reorder = np.zeros_like(sep_matrix)
221-
sep_matrix_reorder[:, :int(sep_matrix_reorder.shape[1]/2)+1] = sep_matrix[:, ::-2]
222-
sep_matrix_reorder[:, int(sep_matrix_reorder.shape[1]/2)+1:] = sep_matrix[:, 1::2]
245+
sep_matrix_reorder[:, : int(sep_matrix_reorder.shape[1] / 2) + 1] = sep_matrix[
246+
:, ::-2
247+
]
248+
sep_matrix_reorder[:, int(sep_matrix_reorder.shape[1] / 2) + 1 :] = sep_matrix[
249+
:, 1::2
250+
]
223251
return sep_matrix_reorder
224252

225253

226-
def generate_otf(psf, lattice_period, phase_step, nphases=3, norientations=1, norders=3):
254+
def generate_otf(
255+
psf, lattice_period, phase_step, nphases=3, norientations=1, norders=3
256+
):
227257
"""Generate the OTF from the PSF.
228258
229259
Fourier transform and separate information components.
@@ -252,31 +282,40 @@ def generate_otf(psf, lattice_period, phase_step, nphases=3, norientations=1, no
252282
"""
253283

254284
psf_arr = itk.array_view_from_image(psf)
255-
spacing = np.asarray(itk.spacing(psf))[::-1] # z, y, x
256-
dk_psf = 1./(psf_arr.shape[:3] * spacing)
285+
spacing = np.asarray(itk.spacing(psf))[::-1] # z, y, x
286+
dk_psf = 1.0 / (psf_arr.shape[:3] * spacing)
257287

258288
otf = np.zeros(psf_arr.shape[:3] + (norders, norientations), dtype=np.complex128)
259289

260-
sep_matrix = make_forward_separation_matrix(nphases, norders,
261-
lattice_period, phase_step)
290+
sep_matrix = make_forward_separation_matrix(
291+
nphases, norders, lattice_period, phase_step
292+
)
262293
inv_sep_matrix = np.linalg.pinv(sep_matrix)
263294

264295
for orientation in range(norientations):
265296
Dr = np.zeros_like(psf_arr)
266297
Dk = np.zeros(psf_arr.shape, dtype=np.complex128)
267298

268299
for phase in range(nphases):
269-
Dr[:,:,:,phase:phase+1] = psf_arr[:,:,:,phase+orientation*nphases::nphases*norientations]
270-
Dk[:,:,:,phase] = np.fft.fftshift(np.fft.ifftn(np.fft.ifftshift(Dr[:,:,:,phase]))) * np.prod(dk_psf)
300+
Dr[:, :, :, phase : phase + 1] = psf_arr[
301+
:, :, :, phase + orientation * nphases :: nphases * norientations
302+
]
303+
Dk[:, :, :, phase] = np.fft.fftshift(
304+
np.fft.ifftn(np.fft.ifftshift(Dr[:, :, :, phase]))
305+
) * np.prod(dk_psf)
271306

272307
# Separate OFT orders by solving the linear system of equations for each
273308
# pixel
274309
for ii in range(nphases):
275310
for kk in range(nphases):
276-
otf[:,:,:,ii,orientation] = otf[:,:,:,ii,orientation] + inv_sep_matrix[ii,kk]*Dk[:,:,:,kk]
311+
otf[:, :, :, ii, orientation] = (
312+
otf[:, :, :, ii, orientation]
313+
+ inv_sep_matrix[ii, kk] * Dk[:, :, :, kk]
314+
)
277315

278316
return otf
279317

318+
280319
def normalize_otf(otf, spacing, norientations=1, norders=3):
281320
"""Normalize the OTF's so that the 0th order of each orientation has unit
282321
energy.
@@ -301,13 +340,15 @@ def normalize_otf(otf, spacing, norientations=1, norders=3):
301340
"""
302341

303342
normalized_otf = np.copy(otf)
304-
dk_psf = 1./(otf.shape[:3] * np.asarray(spacing))
343+
dk_psf = 1.0 / (otf.shape[:3] * np.asarray(spacing))
305344

306345
for orientation in range(norientations):
307-
otf_0 = otf[:,:,:,int(np.ceil(norders/2.)),orientation]
346+
otf_0 = otf[:, :, :, int(np.ceil(norders / 2.0)), orientation]
308347
otf_0_ravel = otf_0.ravel()
309348
energy = np.sum(otf_0_ravel * np.conj(otf_0_ravel * np.prod(dk_psf)))
310-
normalized_otf[:,:,:,:,orientation] = otf[:,:,:,:,orientation] / np.sqrt(energy)
349+
normalized_otf[:, :, :, :, orientation] = otf[
350+
:, :, :, :, orientation
351+
] / np.sqrt(energy)
311352

312353
return normalized_otf
313354

@@ -327,6 +368,7 @@ def save_otf(otf, filename):
327368

328369
np.save(filename, otf)
329370

371+
330372
def load_otf(filename):
331373
"""Load the OTF from a file.
332374

simtk/pydra.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
"""simtk pydra tasks and workflows."""
22

33
# __all__ = [
4-
# 'load_image_task'
5-
# ]
4+
# 'load_image_task'
5+
# ]
66

77
# import numpy as np
88
# from pydra import mark
@@ -11,5 +11,5 @@
1111
# from simtk import load_image
1212

1313
# load_image_annotated = mark.annotate({'filename': str, 'nphases': int,
14-
# 'norientations': int, 'spacing': np.ndarray, 'return': itk.VectorImage })(load_image)
14+
# 'norientations': int, 'spacing': np.ndarray, 'return': itk.VectorImage })(load_image)
1515
# load_image_task = mark.task(load_image_annotated)()

tests/test_pydra.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@
66
import numpy as np
77

88
script_dir = Path(__file__).resolve().parent
9-
data_dir = (script_dir / '..' / 'data').resolve()
10-
if not (data_dir / 'input' / 'Cell_3phase.tif').exists():
11-
print('Testing data not available.')
9+
data_dir = (script_dir / ".." / "data").resolve()
10+
if not (data_dir / "input" / "Cell_3phase.tif").exists():
11+
print("Testing data not available.")
1212
sys.exit(1)
13-
package_dir = (script_dir / '..').resolve()
13+
package_dir = (script_dir / "..").resolve()
1414
sys.path.insert(0, str(package_dir))
1515

16-
test_psf_file = str(data_dir / 'input' / 'PSF_3phase.tif')
16+
test_psf_file = str(data_dir / "input" / "PSF_3phase.tif")
1717

1818
import simtk.pydra
1919

20+
2021
def test_import_simtk_pydra():
21-
assert 'simtk' in simtk.pydra.__doc__
22-
assert 'pydra' in simtk.pydra.__doc__
22+
assert "simtk" in simtk.pydra.__doc__
23+
assert "pydra" in simtk.pydra.__doc__

0 commit comments

Comments
 (0)