Skip to content

Commit df357d7

Browse files
author
Joel Bernier
committed
cleanup of powder ring utils
1 parent 1f7d4ce commit df357d7

File tree

1 file changed

+80
-93
lines changed

1 file changed

+80
-93
lines changed

hexrd/instrument.py

Lines changed: 80 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
from hexrd import matrixutil as mutil
4848
from hexrd.valunits import valWUnit
4949
from hexrd.xrd.transforms_CAPI import anglesToGVec, \
50-
angularDifference, \
5150
detectorXYToGvec, \
5251
gvecToDetectorXY, \
5352
makeDetectorRotMat, \
@@ -510,23 +509,20 @@ def extract_line_positions(self, plane_data, imgser_dict,
510509
collapse_eta=True, collapse_tth=False,
511510
do_interpolation=True):
512511
"""
513-
TODO: handle wedge boundaries
512+
export 'caked' sector data over an instrument
514513
515-
FIXME: must handle merged ranges!!!
514+
FIXME: must handle merged ranges (fixed by JVB 2018/06/28)
516515
"""
517-
if tth_tol is None:
518-
tth_tol = np.degrees(plane_data.tThWidth)
519-
tol_vec = 0.5*np.radians(
520-
[-tth_tol, -eta_tol,
521-
-tth_tol, eta_tol,
522-
tth_tol, eta_tol,
523-
tth_tol, -eta_tol])
524-
#
525-
# pbar = ProgressBar(
526-
# widgets=[Bar('>'), ' ', ETA(), ' ', ReverseBar('<')],
527-
# maxval=self.num_panels,
528-
# ).start()
529-
#
516+
517+
plane_data = plane_data.makeNew() # make local copy to munge
518+
if tth_tol is not None:
519+
plane_data.tThWidth = np.radians(tth_tol)
520+
tth_ranges = np.degrees(plane_data.getMergedRanges()[1])
521+
tth_tols = np.vstack([i[1] - i[0] for i in tth_ranges])
522+
523+
# =====================================================================
524+
# LOOP OVER DETECTORS
525+
# =====================================================================
530526
panel_data = dict.fromkeys(self.detectors)
531527
for i_det, detector_id in enumerate(self.detectors):
532528
print("working on detector '%s'..." % detector_id)
@@ -547,48 +543,30 @@ def extract_line_positions(self, plane_data, imgser_dict,
547543
# make rings
548544
pow_angs, pow_xys = panel.make_powder_rings(
549545
plane_data, merge_hkls=True, delta_eta=eta_tol)
550-
n_rings = len(pow_angs)
551546

547+
# =================================================================
548+
# LOOP OVER RING SETS
549+
# =================================================================
552550
ring_data = []
553-
for i_ring in range(n_rings):
551+
for i_ring, these_data in enumerate(zip(pow_angs, pow_xys)):
554552
print("working on ring %d..." % i_ring)
555-
these_angs = pow_angs[i_ring]
556-
557-
# make sure no one falls off...
558-
npts = len(these_angs)
559-
patch_vertices = (np.tile(these_angs, (1, 4)) +
560-
np.tile(tol_vec, (npts, 1))
561-
).reshape(4*npts, 2)
562-
563-
# find points that fall on the panel
564-
# WARNING: ignoring effect of crystal tvec
565-
det_xy, rMat_s = xrdutil._project_on_detector_plane(
566-
np.hstack([patch_vertices, np.zeros((4*npts, 1))]),
567-
panel.rmat, ct.identity_3x3, self.chi,
568-
panel.tvec, ct.zeros_3, self.tvec,
569-
panel.distortion)
570-
tmp_xy, on_panel = panel.clip_to_panel(det_xy)
571-
572-
# all vertices must be on...
573-
patch_is_on = np.all(on_panel.reshape(npts, 4), axis=1)
574-
575-
# reflection angles (voxel centers) and
576-
# pixel size in (tth, eta)
577-
ang_centers = these_angs[patch_is_on]
578-
ang_pixel_size = panel.angularPixelSize(tmp_xy[::4, :])
553+
554+
# points are already checked to fall on detector
555+
angs = these_data[0]
556+
xys = these_data[1]
579557

580558
# make the tth,eta patches for interpolation
581559
patches = xrdutil.make_reflection_patches(
582-
instr_cfg, ang_centers, ang_pixel_size,
583-
tth_tol=tth_tol, eta_tol=eta_tol,
560+
instr_cfg, angs, panel.angularPixelSize(xys),
561+
tth_tol=tth_tols[i_ring], eta_tol=eta_tol,
584562
distortion=panel.distortion,
585563
npdiv=npdiv, quiet=True,
586564
beamVec=self.beam_vector)
587565

588566
# loop over patches
589567
# FIXME: fix initialization
590568
if collapse_tth:
591-
patch_data = np.zeros((len(ang_centers), n_images))
569+
patch_data = np.zeros((len(angs), n_images))
592570
else:
593571
patch_data = []
594572
for i_p, patch in enumerate(patches):
@@ -599,7 +577,7 @@ def extract_line_positions(self, plane_data, imgser_dict,
599577
vtx_angs[1][[0, -1], 0])
600578
else:
601579
ang_data = (vtx_angs[0][0, :],
602-
ang_centers[i_p][-1])
580+
angs[i_p][-1])
603581
prows, pcols = areas.shape
604582
area_fac = areas/float(native_area)
605583
# need to reshape eval pts for interpolation
@@ -1596,35 +1574,49 @@ def make_powder_rings(
15961574
self, pd, merge_hkls=False, delta_tth=None,
15971575
delta_eta=10., eta_period=None,
15981576
rmat_s=ct.identity_3x3, tvec_s=ct.zeros_3,
1599-
tvec_c=ct.zeros_3, output_ranges=False, output_etas=False):
1577+
tvec_c=ct.zeros_3, full_output=False):
16001578
"""
16011579
"""
16021580
# in case you want to give it tth angles directly
16031581
if hasattr(pd, '__len__'):
16041582
tth = np.array(pd).flatten()
1583+
if delta_tth is None:
1584+
raise RuntimeError(
1585+
"If supplying a 2theta list as first arg, "
1586+
+ "must supply a delta_tth")
1587+
sector_vertices = np.tile(
1588+
0.5*np.radians([-delta_tth, -delta_eta,
1589+
-delta_tth, delta_eta,
1590+
delta_tth, delta_eta,
1591+
delta_tth, -delta_eta,
1592+
0.0, 0.0]), (len(tth), 1)
1593+
)
16051594
else:
1606-
if merge_hkls:
1607-
tth_idx, tth_ranges = pd.getMergedRanges()
1608-
if output_ranges:
1609-
tth = np.r_[tth_ranges].flatten()
1610-
else:
1611-
tth = np.array([0.5*sum(i) for i in tth_ranges])
1595+
# Okay, we have a PlaneData object
1596+
pd = PlaneData.makeNew(pd) # make a copy to munge
1597+
if delta_tth is not None:
1598+
pd.tThWidth = np.radians(delta_tth)
16121599
else:
1613-
if output_ranges:
1614-
tth = pd.getTThRanges().flatten()
1615-
else:
1616-
tth = pd.getTTh()
1600+
delta_tth = np.degrees(pd.tThWidth)
16171601

1618-
if delta_tth is not None:
1619-
pd.tThWidth = np.radians(delta_tth)
1620-
else:
1621-
delta_tth = np.degrees(pd.tThWidth)
1622-
sector_vec = 0.5*np.radians(
1623-
[-delta_tth, -delta_eta,
1624-
-delta_tth, delta_eta,
1625-
delta_tth, delta_eta,
1626-
delta_tth, -delta_eta]
1627-
)
1602+
# conversions, meh...
1603+
del_eta = np.radians(delta_eta)
1604+
1605+
# do merging if asked
1606+
if merge_hkls:
1607+
_, tth_ranges = pd.getMergedRanges()
1608+
tth = np.array([0.5*sum(i) for i in tth_ranges])
1609+
else:
1610+
tth_ranges = pd.getTThRanges()
1611+
tth = pd.getTTh()
1612+
tth_pm = tth_ranges - np.tile(tth, (2, 1)).T
1613+
sector_vertices = np.vstack(
1614+
[[i[0], -del_eta,
1615+
i[0], del_eta,
1616+
i[1], del_eta,
1617+
i[1], -del_eta,
1618+
0.0, 0.0]
1619+
for i in tth_pm])
16281620

16291621
# for generating rings
16301622
if eta_period is None:
@@ -1642,49 +1634,43 @@ def make_powder_rings(
16421634
valid_ang = []
16431635
valid_xy = []
16441636
map_indices = []
1637+
npp = 5 # [ll, ul, ur, lr, center]
16451638
for i_ring in range(len(angs)):
1639+
# expand angles to patch vertices
16461640
these_angs = angs[i_ring].T
1647-
gVec_ring_l = anglesToGVec(these_angs, bHat_l=self.bvec)
1648-
xydet_ring = gvecToDetectorXY(
1649-
gVec_ring_l,
1650-
self.rmat, rmat_s, ct.identity_3x3,
1651-
self.tvec, tvec_s, tvec_c,
1652-
beamVec=self.bvec)
1653-
xydet_ring, on_panel = self.clip_to_panel(xydet_ring)
1654-
nangs_r = len(xydet_ring)
1655-
1656-
# now expand and check to see which sectors (patches) fall off
16571641
patch_vertices = (
1658-
np.tile(these_angs[on_panel, :2], (1, 4)) +
1659-
np.tile(sector_vec, (nangs_r, 1))
1660-
).reshape(4*nangs_r, 2)
1642+
np.tile(these_angs[:, :2], (1, npp))
1643+
+ np.tile(sector_vertices[i_ring], (neta, 1))
1644+
).reshape(npp*neta, 2)
16611645

16621646
# duplicate ome array
16631647
ome_dupl = np.tile(
1664-
these_angs[on_panel, 2], (4, 1)
1665-
).T.reshape(len(patch_vertices), 1)
1648+
these_angs[:, 2], (npp, 1)
1649+
).T.reshape(npp*neta, 1)
16661650

1667-
# find vertices that fall on the panel
1651+
# find vertices that all fall on the panel
16681652
gVec_ring_l = anglesToGVec(
16691653
np.hstack([patch_vertices, ome_dupl]),
16701654
bHat_l=self.bvec)
1671-
tmp_xy = gvecToDetectorXY(
1655+
all_xy = gvecToDetectorXY(
16721656
gVec_ring_l,
16731657
self.rmat, rmat_s, ct.identity_3x3,
16741658
self.tvec, tvec_s, tvec_c,
16751659
beamVec=self.bvec)
1676-
tmp_xy, on_panel_p = self.clip_to_panel(tmp_xy)
1660+
_, on_panel = self.clip_to_panel(all_xy)
16771661

16781662
# all vertices must be on...
1679-
patch_is_on = np.all(on_panel_p.reshape(nangs_r, 4), axis=1)
1663+
patch_is_on = np.all(on_panel.reshape(neta, npp), axis=1)
1664+
patch_xys = all_xy.reshape(neta, 5, 2)[patch_is_on]
16801665

1681-
idx = np.where(on_panel)[0][patch_is_on]
1666+
idx = np.where(patch_is_on)[0]
16821667

1683-
valid_ang.append(these_angs[idx, :2])
1684-
valid_xy.append(xydet_ring[patch_is_on])
1668+
valid_ang.append(these_angs[patch_is_on, :2])
1669+
valid_xy.append(patch_xys[:, -1, :].squeeze())
16851670
map_indices.append(idx)
16861671
pass
1687-
if output_etas:
1672+
# ??? is this option necessary?
1673+
if full_output:
16881674
return valid_ang, valid_xy, map_indices, eta
16891675
else:
16901676
return valid_ang, valid_xy
@@ -2264,13 +2250,14 @@ def __init__(self, image_series_dict, instrument, plane_data,
22642250
np.radians(np.r_[omegas_array[:, 0], omegas_array[-1, 1]]),
22652251
np.radians(ome_period)
22662252
)
2267-
2253+
22682254
# !!! must avoid the case where omeEdges[0] = omeEdges[-1] for the
22692255
# indexer to work properly
22702256
if abs(self._omeEdges[0] - self._omeEdges[-1]) <= ct.sqrt_epsf:
2271-
del_ome = np.radians(omegas_array[0, 1] - omegas_array[0, 0]) # signed
2257+
# !!! SIGNED delta ome
2258+
del_ome = np.radians(omegas_array[0, 1] - omegas_array[0, 0])
22722259
self._omeEdges[-1] = self._omeEdges[-2] + del_ome
2273-
2260+
22742261
# handle etas
22752262
# WARNING: unlinke the omegas in imageseries metadata,
22762263
# these are in RADIANS and represent bin centers

0 commit comments

Comments
 (0)