def test_deepcopy(self, pc1): """Yields the expected parameters and an actual deep copy.""" detector1 = EBSDDetector(pc=pc1) detector2 = detector1.deepcopy() detector1.pcx += 0.1 assert np.allclose(detector1.pcx, 0.521) assert np.allclose(detector2.pcx, 0.421)
def test_set_pc_from_tsl_oxford(self, pc, convention, desired_pc): """PC TSL -> Bruker -> TSL.""" det = EBSDDetector(pc=pc, convention=convention) assert np.allclose(det.pc, desired_pc) assert np.allclose(det.pc_tsl(), pc) assert np.allclose( EBSDDetector(pc=det.pc_tsl(), convention="tsl").pc_tsl(), pc)
def test_set_navigation_shape(self, pc, desired_nav_shape, desired_nav_ndim): """Change shape of PC array.""" detector = EBSDDetector(pc=pc) detector.navigation_shape = desired_nav_shape assert detector.navigation_shape == desired_nav_shape assert detector.navigation_dimension == desired_nav_ndim assert detector.pc.shape == desired_nav_shape + (3, )
def test_set_pc_coordinates(self, pc1): """Returns desired arrays with desired shapes.""" ny, nx = (2, 3) nav_shape = (ny, nx) n = ny * nx detector = EBSDDetector(pc=np.tile(pc1, nav_shape + (1, ))) assert detector.navigation_shape == nav_shape new_pc = np.zeros(nav_shape + (3, )) new_pc[..., 0] = pc1[0] * 0.01 * np.arange(n).reshape(nav_shape) new_pc[..., 1] = pc1[1] * 0.01 * np.arange(n).reshape(nav_shape) new_pc[..., 2] = pc1[2] * 0.01 * np.arange(n).reshape(nav_shape) detector.pcx = new_pc[..., 0] detector.pcy = new_pc[..., 1] detector.pcz = new_pc[..., 2] assert np.allclose(detector.pc, new_pc)
def test_repr(self, pc1): """Expected string representation.""" assert repr( EBSDDetector( shape=(1, 2), px_size=3, binning=4, tilt=5, pc=pc1)) == ( "EBSDDetector (1, 2), px_size 3 um, binning 4, tilt 5, pc " "(0.421, 0.779, 0.505)")
def test_passing_results_from_get_patterns(self): s = nickel_ebsd_small() print(s) s.remove_static_background() s.remove_dynamic_background() mp = nickel_ebsd_master_pattern_small(projection="lambert") r = Rotation([ [0.9522, -0.0151, -0.2883, 0.1001], # Left grain [0.9534, 0.0465, -0.2187, -0.2026], # Right grain [0.8876, -0.2312, 0.3364, -0.2131], # 50th best match ]) detector = EBSDDetector( shape=s.axes_manager.signal_shape[::-1], pc=[0.421, 0.7794, 0.5049], convention="tsl", sample_tilt=70, ) sim = mp.get_patterns(rotations=r, detector=detector, energy=20) xmap = s.match_patterns(sim, keep_n=1) scores = xmap.scores.reshape(xmap.size, ) sim_idx = xmap.simulation_indices.reshape(xmap.size, ) assert np.allclose( scores, [0.197, 0.188, 0.207, 0.198, 0.186, 0.225, 0.191, 0.191, 0.206], atol=1e-3, ) assert np.allclose(sim_idx, [0, 1, 1, 0, 1, 1, 0, 1, 1])
def test_nav_shape_dim( self, pc1, nav_shape, desired_nav_shape, desired_nav_dim ): """Navigation shape and dimension is derived correctly from PC shape.""" det = EBSDDetector(pc=np.tile(pc1, nav_shape)) assert det.navigation_shape == desired_nav_shape assert det.navigation_dimension == desired_nav_dim
def test_init(self, pc1): """Initialization works.""" shape = (1, 2) px_size = 3 binning = 4 tilt = 5 det = EBSDDetector( shape=shape, px_size=px_size, binning=binning, tilt=tilt, pc=pc1, ) assert det.shape == shape assert det.aspect_ratio == 0.5
def detector(request, pc1): """A NORDIF UF1100 EBSD detector with a TSL PC.""" return EBSDDetector( shape=(60, 60), binning=8, px_size=70, pc=np.ones(request.param + (3, )) * pc1, sample_tilt=70, tilt=0, convention="tsl", )
def test_property_shapes(self, shape, desired_shapes): """Expected property shapes when varying navigation shape.""" det = EBSDDetector(pc=np.ones(shape + (3, ))) assert det.bounds.shape == desired_shapes[0] assert det.x_min.shape == desired_shapes[1] assert det.y_min.shape == desired_shapes[2] assert det.x_range.shape == desired_shapes[3] assert det.y_range.shape == desired_shapes[4] assert det.x_scale.shape == desired_shapes[5] assert det.y_scale.shape == desired_shapes[6] assert det.gnomonic_bounds.shape == desired_shapes[7]
def test_set_pc_from_emsoft_no_version(self): """PC EMsoft -> Bruker, no EMsoft version specified gives v5.""" assert np.allclose( EBSDDetector( shape=(60, 60), pc=[-3.4848, 114.2016, 15767.7], px_size=59.2, binning=8, convention="emsoft", ).pc, [0.50726, 0.26208, 0.55849], atol=1e-2, )
def nickel_zone_axes(nickel_kikuchi_band, nickel_rotations, pc1): bands = nickel_kikuchi_band hkl = bands.hkl.data phase = bands.phase nav_shape = (5, 5) detector = EBSDDetector( shape=(60, 60), binning=8, px_size=70, pc=np.ones(nav_shape + (3, )) * pc1, sample_tilt=70, tilt=0, convention="tsl", ) nav_dim = detector.navigation_dimension navigation_axes = (1, 2)[:nav_dim] n_hkl = bands.size n_hkl2 = n_hkl**2 uvw = np.cross(hkl[:, np.newaxis, :], hkl).reshape((n_hkl2, 3)) not000 = np.count_nonzero(uvw, axis=1) != 0 uvw = uvw[not000] with np.errstate(divide="ignore", invalid="ignore"): uvw = uvw / np.gcd.reduce(uvw, axis=1)[:, np.newaxis] uvw = np.unique(uvw, axis=0).astype(int) det2direct = detector2direct_lattice( sample_tilt=detector.sample_tilt, detector_tilt=detector.tilt, lattice=phase.structure.lattice, rotation=nickel_rotations.reshape(*nav_shape), ) uvw_detector = np.tensordot(uvw, det2direct, axes=(1, 0)) upper_hemisphere = uvw_detector[..., 2] > 0 is_in_some_pattern = np.sum(upper_hemisphere, axis=navigation_axes) != 0 uvw = uvw[is_in_some_pattern, ...] uvw_in_pattern = upper_hemisphere[is_in_some_pattern, ...].T uvw_detector = np.moveaxis(uvw_detector[is_in_some_pattern], source=0, destination=nav_dim) return ZoneAxis( phase=phase, uvw=uvw, uvw_detector=uvw_detector, in_pattern=uvw_in_pattern, gnomonic_radius=detector.r_max, )
def nickel_kikuchi_band(nickel_rlp, nickel_rotations, pc1): rlp = nickel_rlp.symmetrise() phase = rlp.phase hkl = rlp.hkl.data nav_shape = (5, 5) detector = EBSDDetector( shape=(60, 60), binning=8, px_size=70, pc=np.ones(nav_shape + (3, )) * pc1, sample_tilt=70, tilt=0, convention="tsl", ) nav_dim = detector.navigation_dimension navigation_axes = (1, 2)[:nav_dim] # Output shape is (3, n, 3) or (3, ny, nx, 3) det2recip = detector2reciprocal_lattice( sample_tilt=detector.sample_tilt, detector_tilt=detector.tilt, lattice=phase.structure.lattice, rotation=nickel_rotations.reshape(*nav_shape), ) # Output shape is (nhkl, n, 3) or (nhkl, ny, nx, 3) hkl_detector = np.tensordot(hkl, det2recip, axes=(1, 0)) # Determine whether a band is visible in a pattern upper_hemisphere = hkl_detector[..., 2] > 0 is_in_some_pattern = np.sum(upper_hemisphere, axis=navigation_axes) != 0 # Get bands that are in some pattern and their coordinates in the # proper shape hkl = hkl[is_in_some_pattern, ...] hkl_in_pattern = upper_hemisphere[is_in_some_pattern, ...].T hkl_detector = np.moveaxis(hkl_detector[is_in_some_pattern], source=0, destination=nav_dim) return KikuchiBand( phase=phase, hkl=hkl, hkl_detector=hkl_detector, in_pattern=hkl_in_pattern, gnomonic_radius=detector.r_max, )
def __init__( self, detector: EBSDDetector, phase: Phase, rotations: Rotation, ): """A generator storing necessary parameters to simulate geometrical EBSD patterns. Parameters ---------- detector Detector describing the detector-sample geometry. phase A phase container with a crystal structure and a space and point group describing the allowed symmetry operations. rotations Unit cell rotations to simulate patterns for. The navigation shape of the resulting simulation is determined from the rotations' shape, with a maximum dimension of 2. Examples -------- >>> from orix.crystal_map import Phase >>> from orix.quaternion import Rotation >>> from kikuchipy.detectors import EBSDDetector >>> from kikuchipy.generators import EBSDSimulationGenerator >>> det = EBSDDetector( ... shape=(60, 60), sample_tilt=70, pc=[0.5,] * 3 ... ) >>> p = Phase(name="ni", space_group=225) >>> p.structure.lattice.setLatPar(3.52, 3.52, 3.52, 90, 90, 90) >>> simgen = EBSDSimulationGenerator( ... detector=det, ... phase=p, ... rotations=Rotation.from_euler([90, 45, 90]) ... ) >>> simgen EBSDSimulationGenerator (1,) EBSDDetector (60, 60), px_size 1 um, binning 1, tilt 0, pc (0.5, 0.5, 0.5) <name: . space group: None. point group: None. proper point group: None. color: tab:blue> Rotation (1,) """ self.detector = detector.deepcopy() self.phase = phase.deepcopy() self.rotations = deepcopy(rotations)
def test_simulated_patterns_xmap_detector(self): mp = nickel_ebsd_master_pattern_small(projection="lambert") r = Rotation.from_euler([[0, 0, 0], [0, np.pi / 2, 0]]) detector = EBSDDetector( shape=(60, 60), pc=[0.5, 0.5, 0.5], sample_tilt=70, convention="tsl", ) s = mp.get_patterns(rotations=r, detector=detector, energy=20) assert np.allclose(s.xmap.rotations.to_euler(), r.to_euler()) assert s.xmap.phases.names == [mp.phase.name] assert s.xmap.phases[0].point_group.name == mp.phase.point_group.name assert s.detector.shape == detector.shape assert np.allclose(s.detector.pc, detector.pc) assert s.detector.sample_tilt == detector.sample_tilt
def test_detector_dimensions( self, shape, px_size, binning, pc, ssd, width, height, size, shape_unbinned, px_size_binned, ): """Initialization yields expected derived values.""" detector = EBSDDetector( shape=shape, px_size=px_size, binning=binning, pc=pc ) assert detector.specimen_scintillator_distance == ssd assert detector.width == width assert detector.height == height assert detector.size == size assert detector.unbinned_shape == shape_unbinned assert detector.px_size_binned == px_size_binned
def test_set_pc_from_emsoft(self, shape, pc, px_size, binning, version, desired_pc): """PC EMsoft -> Bruker -> EMsoft, also checking to_tsl() and to_bruker(). """ det = EBSDDetector( shape=shape, pc=pc, px_size=px_size, binning=binning, convention=f"emsoft{version}", ) assert np.allclose(det.pc, desired_pc, atol=1e-2) assert np.allclose(det.pc_emsoft(version=version), pc, atol=1e-2) assert np.allclose(det.pc_bruker(), desired_pc, atol=1e-2) pc_tsl = deepcopy(det.pc) pc_tsl[..., 1] = 1 - pc_tsl[..., 1] assert np.allclose(det.pc_tsl(), pc_tsl, atol=1e-2) assert np.allclose(det.pc_oxford(), pc_tsl, atol=1e-2)
def test_pc_initialization(self, pc1, pc_type): """Initialize PC of valid types.""" det = EBSDDetector(pc=pc_type(pc1)) assert isinstance(det.pc, np.ndarray)
def test_get_patterns(self): # Ni Test EMSOFT_EBSD_FILE = os.path.join( DIR_PATH, "../../data/emsoft_ebsd/EBSD_TEST_Ni.h5") emsoft_key = load(EMSOFT_EBSD_FILE) emsoft_key = emsoft_key.data[0] angles = np.array((120, 45, 60)) r = Rotation.from_euler(np.radians(angles)) kp_mp = nickel_ebsd_master_pattern_small(projection="lambert", hemisphere="both") kp_pattern = kp_mp.get_patterns(rotations=r, detector=self.detector, energy=20, dtype_out=np.uint8) kp_pat = kp_pattern.data[0].compute() ncc1 = ncc(kp_pat, emsoft_key) ndp1 = ndp(kp_pat, emsoft_key) assert ncc1 >= 0.935 assert ndp1 >= 0.935 detector_shape = self.detector.shape r2 = Rotation.from_euler(((0, 0, 0), (1, 1, 1), (2, 2, 2))) mp_a = EBSDMasterPattern(np.zeros((2, 10, 11, 11))) print(mp_a.axes_manager) mp_a.axes_manager[0].name = "hemisphere" mp_a.axes_manager[1].name = "energy" mp_a.projection = "lambert" mp_a.phase = Phase("Ni", 225) out_a = mp_a.get_patterns(r2, self.detector, 5) assert isinstance(out_a, LazyEBSD) desired_data_shape = (3, ) + detector_shape[::-1] assert out_a.axes_manager.shape == desired_data_shape mp_b = EBSDMasterPattern(np.zeros((10, 11, 11))) mp_b.axes_manager[0].name = "energy" mp_b.projection = "lambert" mp_b.phase = Phase("Ni", 225) out_b = mp_b.get_patterns(r2, self.detector, 5) assert isinstance(out_b, LazyEBSD) assert out_b.axes_manager.shape == desired_data_shape mp_c = EBSDMasterPattern(np.zeros((11, 11))) mp_c.projection = "lambert" mp_c.phase = Phase("Ni", 225) out_c = mp_c.get_patterns(r2, self.detector, 5) out_c_2 = mp_c.get_patterns(r2, self.detector, 5, compute=True) assert isinstance(out_c, LazyEBSD) assert isinstance(out_c_2, EBSD) assert out_c.axes_manager.shape == desired_data_shape mp_c2 = EBSDMasterPattern(np.zeros((11, 11))) mp_c2.projection = "lambert" mp_c2.phase = Phase("!Ni", 220) with pytest.raises(AttributeError): mp_c2.get_patterns(r2, self.detector, 5) mp_d = EBSDMasterPattern(np.zeros((2, 11, 11))) with pytest.raises(NotImplementedError): mp_d.get_patterns(r2, self.detector, 5) mp_e = EBSDMasterPattern(np.zeros((10, 11, 11))) mp_e.axes_manager[0].name = "energy" mp_e.projection = "lambert" mp_e.phase = Phase("!Ni", 220) with pytest.raises(AttributeError): mp_e.get_patterns(r2, self.detector, 5) # More than one Projection center is currently not supported so # it should fail d2 = EBSDDetector( shape=(10, 10), px_size=50, pc=((0, 0, 15000), (0, 0, 15000)), convention="emsoft4", tilt=0, sample_tilt=70, ) with pytest.raises(NotImplementedError): mp_c.get_patterns(r2, d2, 5)
class TestSimulatedPatternDictionary: # Create detector model detector = EBSDDetector( shape=(480, 640), px_size=50, pc=(20, 20, 15000), convention="emsoft4", tilt=10, sample_tilt=70, ) def test_get_direction_cosines(self): out = _get_direction_cosines(self.detector) assert isinstance(out, Vector3d) def test_get_lambert_interpolation_parameters(self): dc = _get_direction_cosines(self.detector) npx = 1001 npy = 1001 scale = 500 ( nii, nij, niip, nijp, di, dj, dim, djm, ) = _get_lambert_interpolation_parameters( rotated_direction_cosines=dc, npx=npx, npy=npy, scale=scale, ) assert (nii <= niip).all() assert (nij <= nijp).all() assert (nii < npx).all() assert (nij < npy).all() assert (niip < npx).all() assert (nijp < npx).all() assert (nii >= 0).all() assert (nij >= 0).all() assert (niip >= 0).all() assert (nijp >= 0).all() def test_get_patterns(self): # Ni Test EMSOFT_EBSD_FILE = os.path.join( DIR_PATH, "../../data/emsoft_ebsd/EBSD_TEST_Ni.h5") emsoft_key = load(EMSOFT_EBSD_FILE) emsoft_key = emsoft_key.data[0] angles = np.array((120, 45, 60)) r = Rotation.from_euler(np.radians(angles)) kp_mp = nickel_ebsd_master_pattern_small(projection="lambert", hemisphere="both") kp_pattern = kp_mp.get_patterns(rotations=r, detector=self.detector, energy=20, dtype_out=np.uint8) kp_pat = kp_pattern.data[0].compute() ncc1 = ncc(kp_pat, emsoft_key) ndp1 = ndp(kp_pat, emsoft_key) assert ncc1 >= 0.935 assert ndp1 >= 0.935 detector_shape = self.detector.shape r2 = Rotation.from_euler(((0, 0, 0), (1, 1, 1), (2, 2, 2))) mp_a = EBSDMasterPattern(np.zeros((2, 10, 11, 11))) print(mp_a.axes_manager) mp_a.axes_manager[0].name = "hemisphere" mp_a.axes_manager[1].name = "energy" mp_a.projection = "lambert" mp_a.phase = Phase("Ni", 225) out_a = mp_a.get_patterns(r2, self.detector, 5) assert isinstance(out_a, LazyEBSD) desired_data_shape = (3, ) + detector_shape[::-1] assert out_a.axes_manager.shape == desired_data_shape mp_b = EBSDMasterPattern(np.zeros((10, 11, 11))) mp_b.axes_manager[0].name = "energy" mp_b.projection = "lambert" mp_b.phase = Phase("Ni", 225) out_b = mp_b.get_patterns(r2, self.detector, 5) assert isinstance(out_b, LazyEBSD) assert out_b.axes_manager.shape == desired_data_shape mp_c = EBSDMasterPattern(np.zeros((11, 11))) mp_c.projection = "lambert" mp_c.phase = Phase("Ni", 225) out_c = mp_c.get_patterns(r2, self.detector, 5) out_c_2 = mp_c.get_patterns(r2, self.detector, 5, compute=True) assert isinstance(out_c, LazyEBSD) assert isinstance(out_c_2, EBSD) assert out_c.axes_manager.shape == desired_data_shape mp_c2 = EBSDMasterPattern(np.zeros((11, 11))) mp_c2.projection = "lambert" mp_c2.phase = Phase("!Ni", 220) with pytest.raises(AttributeError): mp_c2.get_patterns(r2, self.detector, 5) mp_d = EBSDMasterPattern(np.zeros((2, 11, 11))) with pytest.raises(NotImplementedError): mp_d.get_patterns(r2, self.detector, 5) mp_e = EBSDMasterPattern(np.zeros((10, 11, 11))) mp_e.axes_manager[0].name = "energy" mp_e.projection = "lambert" mp_e.phase = Phase("!Ni", 220) with pytest.raises(AttributeError): mp_e.get_patterns(r2, self.detector, 5) # More than one Projection center is currently not supported so # it should fail d2 = EBSDDetector( shape=(10, 10), px_size=50, pc=((0, 0, 15000), (0, 0, 15000)), convention="emsoft4", tilt=0, sample_tilt=70, ) with pytest.raises(NotImplementedError): mp_c.get_patterns(r2, d2, 5) # TODO: Create tests for other structures def test_get_patterns_chunk(self): r = Rotation.from_euler(((0, 0, 0), (1, 1, 1), (2, 2, 2))) dc = _get_direction_cosines(self.detector) mpn = np.empty((1001, 1001)) mps = mpn npx = 1001 npy = npx out = _get_patterns_chunk( rotations_array=r.data, dc=dc, master_north=mpn, master_south=mps, npx=npx, npy=npy, scale=(npx - 1) / 2, rescale=False, ) assert out.shape == r.shape + dc.shape def test_simulated_patterns_xmap_detector(self): mp = nickel_ebsd_master_pattern_small(projection="lambert") r = Rotation.from_euler([[0, 0, 0], [0, np.pi / 2, 0]]) detector = EBSDDetector( shape=(60, 60), pc=[0.5, 0.5, 0.5], sample_tilt=70, convention="tsl", ) s = mp.get_patterns(rotations=r, detector=detector, energy=20) assert np.allclose(s.xmap.rotations.to_euler(), r.to_euler()) assert s.xmap.phases.names == [mp.phase.name] assert s.xmap.phases[0].point_group.name == mp.phase.point_group.name assert s.detector.shape == detector.shape assert np.allclose(s.detector.pc, detector.pc) assert s.detector.sample_tilt == detector.sample_tilt @pytest.mark.parametrize("nav_shape", [(10, 20), (3, 5), (2, 6)]) def test_get_patterns_navigation_shape(self, nav_shape): mp = nickel_ebsd_master_pattern_small(projection="lambert") r = Rotation(np.random.uniform(low=0, high=1, size=nav_shape + (4, ))) detector = EBSDDetector(shape=(60, 60)) sim = mp.get_patterns(rotations=r, detector=detector, energy=20) assert sim.axes_manager.navigation_shape[::-1] == nav_shape def test_get_patterns_navigation_shape_raises(self): mp = nickel_ebsd_master_pattern_small(projection="lambert") r = Rotation(np.random.uniform(low=0, high=1, size=(1, 2, 3, 4))) detector = EBSDDetector(shape=(60, 60)) with pytest.raises(ValueError, match="The rotations object can only"): _ = mp.get_patterns(rotations=r, detector=detector, energy=20)
from kikuchipy.detectors import EBSDDetector from kikuchipy import load data = "/home/hakon/kode/kikuchipy/kikuchipy/data/kikuchipy/patterns.h5" outdir = "/home/hakon/kode/kikuchipy/doc/_static/image" refframe_dir = os.path.join(outdir, "reference_frames") datadir, fname = os.path.split(data) fname, ext = os.path.splitext(fname) s = load(data) s.remove_static_background() s.remove_dynamic_background() s.rescale_intensity(percentiles=(0.5, 99.5)) det = EBSDDetector(shape=(60, 60), pc=[0.4210, 0.2206, 0.5049]) fig, ax = det.plot(coordinates="detector", pattern=s.inav[0, 0].data, show_pc=True, return_fig_ax=True) arrow_dict1 = { "x": 0, "y": 0, "width": det.nrows * 0.01, "head_width": 3, "head_length": 4, "zorder": 10, "clip_on": False, } arrow_length = det.ncols * 0.2 x_color = "r"
def test_gnomonic_range(self, pc1, shape, desired_x_range, desired_y_range): """Gnomonic x/y range, x depends on aspect ratio.""" detector = EBSDDetector(shape=shape, pc=pc1) assert np.allclose(detector.x_range, desired_x_range) assert np.allclose(detector.y_range, desired_y_range)
def test_gnomonic_scale(self, pc1, shape, desired_x_scale, desired_y_scale): """Gnomonic x/y scale.""" detector = EBSDDetector(shape=shape, pc=pc1) assert np.allclose(detector.x_scale, desired_x_scale, atol=1e-6) assert np.allclose(detector.y_scale, desired_y_scale, atol=1e-6)
def test_set_navigation_shape_raises(self, pc1): """Desired error message.""" detector = EBSDDetector(pc=pc1) with pytest.raises(ValueError, match="A maximum dimension of 2"): detector.navigation_shape = (1, 2, 3)
def test_get_patterns_navigation_shape(self, nav_shape): mp = nickel_ebsd_master_pattern_small(projection="lambert") r = Rotation(np.random.uniform(low=0, high=1, size=nav_shape + (4, ))) detector = EBSDDetector(shape=(60, 60)) sim = mp.get_patterns(rotations=r, detector=detector, energy=20) assert sim.axes_manager.navigation_shape[::-1] == nav_shape
def test_set_pc_convention_raises(self, pc1): """Wrong convention raises.""" with pytest.raises(ValueError, match="Projection center convention "): _ = EBSDDetector(pc=pc1, convention="nordif")
def test_set_pc_from_bruker(self, pc, convention): """PC Bruker returns Bruker PC, which is the default.""" det = EBSDDetector(pc=pc, convention=convention) assert np.allclose(det.pc, pc)
def test_get_patterns_navigation_shape_raises(self): mp = nickel_ebsd_master_pattern_small(projection="lambert") r = Rotation(np.random.uniform(low=0, high=1, size=(1, 2, 3, 4))) detector = EBSDDetector(shape=(60, 60)) with pytest.raises(ValueError, match="The rotations object can only"): _ = mp.get_patterns(rotations=r, detector=detector, energy=20)
def test_pc_average(self, pc, desired_pc_average): """Calculation of PC average.""" assert np.allclose(EBSDDetector(pc=pc).pc_average, desired_pc_average)