Passed
Pull Request — main (#1326)
by Fernando
03:20 queued 01:59
created

torchio.datasets.zone_plate   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 53
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 33
dl 0
loc 53
rs 10
c 0
b 0
f 0
wmc 4

2 Methods

Rating   Name   Duplication   Size   Complexity  
A ZonePlate.__init__() 0 6 2
A ZonePlate._generate_image() 0 23 2
1
import numpy as np
2
3
from ..data import ScalarImage
4
from ..data.subject import Subject
5
6
7
class ZonePlate(Subject):
8
    """Synthetic data generated from a zone plate.
9
10
    The zone plate is a circular diffraction grating that produces concentric
11
    rings of light and dark bands. This dataset is useful for testing image
12
    processing algorithms, particularly those related to frequency analysis and
13
    interpolation.
14
15
    See equation 10.63 in `Practical Handbook on Image Processing for
16
    Scientific Applications <https://www.routledge.com/Practical-Handbook-on-Image-Processing-for-Scientific-and-Technical-Applications/Jahne/p/book/9780849319006?srsltid=AfmBOoptrtzILIlMx9FYqvx6UrGbevfD66x2k242iprFdn_CfyOWXjjH>`_
17
    by Bernd Jähne.
18
19
    Args:
20
        size: The size of the generated image along all dimensions.
21
    """
22
23
    def __init__(self, size: int = 501):
24
        if size < 3:
25
            raise ValueError('Size must be at least 3.')
26
        self.size = size
27
        image = self._generate_image(size)
28
        super().__init__(image=image)
29
30
    @staticmethod
31
    def _generate_image(size: int) -> ScalarImage:
32
        if size % 2 == 1:
33
            fin = (size - 1) // 2
34
            ini = -fin
35
        else:
36
            fin = size // 2
37
            ini = -fin + 1
38
        x = np.arange(ini, fin)
39
        y = np.arange(ini, fin)
40
        z = np.arange(ini, fin)
41
        X, Y, Z = np.meshgrid(x, y, z)
42
        r = np.sqrt(X**2 + Y**2 + Z**2)
43
        km = 0.8 * np.pi
44
        rm = ini
45
        w = rm / 10
46
        term1 = np.sin((km * r**2) / (2 * rm))
47
        term2 = 0.5 * np.tanh((rm - r) / w) + 0.5
48
        g = term1 * term2
49
        affine = np.eye(4)
50
        origin = np.array([ini, ini, ini])
51
        affine[:3, 3] = origin
52
        return ScalarImage(tensor=g[np.newaxis], affine=affine)
53