Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More tests #3

Merged
merged 5 commits into from
Apr 27, 2015
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 89 additions & 3 deletions skxray/roi.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
########################################################################

"""
This module is to get informations of different region of interests(roi's).
Information : the number of pixels, pixel indices, indices
This module is to get information of different region of interests(roi's).
Information : pixel indices, indices array
"""


Expand All @@ -62,6 +62,8 @@

def rectangles(coords, shape):
"""
This function wil provide the indices array for rectangle region of interests.

Parameters
----------
coords : iterable
Expand Down Expand Up @@ -214,7 +216,7 @@ def ring_edges(inner_radius, width, spacing=0, num_rings=None):
if num_rings != len(width):
raise ValueError("num_rings does not match width list")
if spacing_is_list:
if num_rings != len(spacing):
if num_rings-1 != len(spacing):
raise ValueError("num_rings does not match spacing list")

# Now regularlize the input.
Expand All @@ -229,3 +231,87 @@ def ring_edges(inner_radius, width, spacing=0, num_rings=None):
edges = np.cumsum(steps).reshape(-1, 2)

return edges


def divide_pies(image_shape, radius, calibrated_center,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pie_slices(edges, slicing, center, shape, theta0=0) where slicing can be an integer (slicing=8 gives 8 equal-sized slices, like a pizza) or a list of angles in degrees like [0, 70, 190]. In either case theta0 should be added to the resultant angles to provide an easy way to adjust the alignment.

num_angles, rotate='N',):
"""
This function will provide the indices when a circular roi
is divided into pies.

Parameters
----------
image_shape : tuple
shape of the image (detector X and Y direction)
Order is (num_rows, num_columns)

radius : float
radius of the circle

calibrated_center : tuple
defining the center of the image
(column value, row value) (mm)

num_angles : int
number of angles ring divide into
angles are measured from horizontal-anti clock wise

rotate : {'Y', 'N'}, optional
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remember to remove this.

to make angles measured from vertical-anti clock wise

Returns
-------
labels_grid : array
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Call this label_array for consistency.

indices of the required roi's
shape is ([image_shape[0], image_shape[1]])
"""
angle_grid = get_angle_grid(image_shape, calibrated_center)
# required angles
angles = np.linspace(0, 360, num_angles)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

np.isscalar can be used to check whether angles needs to be constructed as it is here, or whether we can just use user input.

# the indices of the bins(angles) to which each value in input
# array(angle_grid) belongs.
ind_grid = (np.digitize(np.ravel(angle_grid), angles,
right=False)).reshape(image_shape)

# radius grid for the image_shape
grid_values = core.pixel_to_radius(image_shape, calibrated_center)

if rotate == 'Y':
ind_grid = np.rot90(ind_grid)

ind_grid[grid_values > radius] = 0

labels_grid = ind_grid.reshape(image_shape)

return labels_grid


def get_angle_grid(image_shape, calibrated_center):
"""
This function will provide angle values for the whole grid
from the calibrated center

Parameters
----------
image_shape : tuple
shape of the image (detector X and Y direction)
Order is (num_rows, num_columns)

calibrated_center : tuple
defining the center of the image
(column value, row value) (mm)

Returns
-------
angle_grid : array
angle values from the calibrated center
shape image_shape
"""
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sameera2004 and I benchmarked this against trackpy's theta_mask (https://github.com/soft-matter/trackpy/blob/master/trackpy/masks.py#L40) and found theta_mask to be 30X times faster. Note that theta_mask assumes r=0 is in the center of the image, which may be the source of perf gains.

yy, xx = np.mgrid[:image_shape[0], :image_shape[1]]
y_ = (np.flipud(yy) - calibrated_center[0])
x_ = (xx - calibrated_center[1])
angle_grid = np.rad2deg(np.arctan2(y_, x_))

angle_grid[angle_grid < 0] = 360 + angle_grid[angle_grid < 0]

return angle_grid
84 changes: 77 additions & 7 deletions skxray/tests/test_roi.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
import numpy.testing as npt


def test_roi_rectangles():
def test_rectangles():
shape = (15, 26)
roi_data = np.array(([2, 2, 6, 3], [6, 7, 8, 5], [8, 18, 5, 10]),
dtype=np.int64)
Expand All @@ -80,17 +80,41 @@ def test_roi_rectangles():
assert_almost_equal(bottom-1, ind_co[-1][-1])


def test_roi_rings():
calibrated_center = (100, 100)
def test_rings():
calibrated_center = (100., 100.)
img_dim = (200, 205)
first_q = 2
delta_q = 3
first_q = 10.
delta_q = 5.
num_rings = 7 # number of Q rings
one_step_q = 5.0
step_q = [2.5, 3.0, 5.8]

# test when there is same spacing between rings
edges = roi.ring_edges(first_q, width=delta_q, spacing=one_step_q,
num_rings=num_rings)
print("edges there is same spacing between rings ", edges)
label_array = roi.rings(edges, calibrated_center, img_dim)
print("label_array there is same spacing between rings", label_array)

# test when there is same spacing between rings
edges = roi.ring_edges(first_q, width=delta_q, spacing=2.5,
num_rings=num_rings)
print("edges there is same spacing between rings ", edges)
label_array = roi.rings(edges, calibrated_center, img_dim)
print("label_array there is same spacing between rings", label_array)

# test when there is different spacing between rings
edges = roi.ring_edges(first_q, width=delta_q, spacing=step_q,
num_rings=4)
print("edges when there is different spacing between rings", edges)
label_array = roi.rings(edges, calibrated_center, img_dim)
print("label_array there is different spacing between rings", label_array)

# test when there is no spacing between rings
edges = roi.ring_edges(first_q, width=delta_q, num_rings=num_rings)
print(edges)
print("edges", edges)
label_array = roi.rings(edges, calibrated_center, img_dim)
print(label_array)
print("label_array", label_array)

# Did we draw the right number of rings?
print(np.unique(label_array))
Expand Down Expand Up @@ -147,3 +171,49 @@ def _helper_check(pixel_list, inds, num_pix, q_ring_val, calib_center,
- 0.000001)]]))[0][0]))
assert_array_equal(zero_grid, data)
assert_array_equal(num_pix, num_pixels)


def test_divide_pies():
detector_size = (100, 80)
radius = 50.
calibrated_center = (50., 20.)
num_angles = 8

angles = np.linspace(0, 360, num_angles)

all_roi_inds = roi.divide_pies(detector_size, radius,
calibrated_center,
num_angles)

labels, indices = corr.extract_label_indices(all_roi_inds)

ty = np.zeros(detector_size).ravel()
ty[indices] = labels

num_pixels = (np.bincount(ty.astype(int)))[1:]

# get the angle grid from the center
angle_grid = roi.get_angle_grid(detector_size, calibrated_center)
# get the indices into a grid
zero_grid = np.zeros((detector_size[0], detector_size[1]))

# radius values from the calibrated
grid_values = core.pixel_to_radius(detector_size, calibrated_center)

zero_grid[grid_values <= radius] = 1

assert_array_equal(np.nonzero(zero_grid),
np.nonzero((ty.reshape(*detector_size))))

mesh = np.zeros((detector_size[0], detector_size[1]))
for i in range(num_angles-1):
vl = ((angles[i] <= angle_grid) &
(angle_grid < angles[i + 1]))
mesh[vl] = i + 1

# remove the values grater than the radius
mesh[grid_values > radius] = 0
# take out the zero values in the grid
roi_inds_m = mesh[mesh > 0]

assert_array_equal(roi_inds_m, labels)