4747from hexrd import matrixutil as mutil
4848from hexrd .valunits import valWUnit
4949from 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