def test_merging_refined_maps(self): ny, nx = (3, 3) nav_size = ny * nx r = Rotation.from_euler(np.ones((nav_size, 3))) x = np.tile(np.arange(ny), nx) y = np.repeat(np.arange(nx), ny) # Simulation indices n_sim_indices = 10 sim_indices1 = np.random.randint(low=0, high=1000, size=n_sim_indices * nav_size).reshape( (nav_size, n_sim_indices)) sim_indices2 = np.random.randint(low=0, high=1000, size=n_sim_indices * nav_size).reshape( (nav_size, n_sim_indices)) # Scores scores1 = np.ones(nav_size) scores1[0] = 3 scores2 = 2 * np.ones(nav_size) xmap1 = CrystalMap( rotations=r, phase_id=np.ones(nav_size) * 0, phase_list=PhaseList(Phase(name="a")), x=x, y=y, prop={ "simulation_indices": sim_indices1, "scores": scores1 }, ) xmap2 = CrystalMap( rotations=r, phase_id=np.ones(nav_size), phase_list=PhaseList(Phase(name="b")), x=x, y=y, prop={ "simulation_indices": sim_indices2, "scores": scores2 }, ) xmap_merged = merge_crystal_maps(crystal_maps=[xmap1, xmap2]) assert "simulation_indices" not in xmap_merged.prop.keys() assert "merged_simulation_indices" not in xmap_merged.prop.keys() with pytest.raises(ValueError, match="Cannot merge maps with more"): _ = merge_crystal_maps( crystal_maps=[xmap1, xmap2], simulation_indices_prop="simulation_indices", )
def test_init_with_different_coordinate_arrays( self, crystal_map_input, expected_shape, expected_size, expected_step_sizes, expected_rotations_per_point, ): cm = CrystalMap(**crystal_map_input) coordinate_arrays = [ crystal_map_input["z"], crystal_map_input["y"], crystal_map_input["x"], ] assert cm.shape == expected_shape assert cm.size == expected_size assert cm._step_sizes == expected_step_sizes assert cm.rotations_per_point == expected_rotations_per_point for actual_coords, expected_coords, expected_step_size in zip( cm._coordinates.values(), coordinate_arrays, expected_step_sizes.values() ): print(actual_coords, expected_coords) if expected_coords is None: assert actual_coords is None else: assert np.allclose(actual_coords, expected_coords)
def test_get_nrows_ncols_step_sizes(self, crystal_map_input, desired_shape, desired_step_sizes): xmap = CrystalMap(**crystal_map_input) nrows, ncols, dy, dx = _get_nrows_ncols_step_sizes(xmap) assert (nrows, ncols) == desired_shape assert (dy, dx) == desired_step_sizes
def test_scalebar_properties(self, crystal_map_input, scalebar_properties, artist_attribute): cm = CrystalMap(**crystal_map_input) cm.scan_unit = "um" fig = plt.figure() ax = fig.add_subplot(projection=PLOT_MAP) _ = ax.plot_map(cm, scalebar=False) sbar = ax.add_scalebar(cm, **scalebar_properties) if "alpha" not in scalebar_properties.keys(): # Check default assert sbar.patch._alpha == 0.6 for (k, v), attr_loc in zip(scalebar_properties.items(), artist_attribute.values()): if isinstance(attr_loc, list): sbar_attr = sbar.__getattribute__(attr_loc[0]) for i in attr_loc[1:]: if isinstance(i, int): sbar_attr = sbar_attr[i] else: sbar_attr = sbar_attr.__getattribute__(i) else: sbar_attr = sbar.__getattribute__(attr_loc) assert sbar_attr == v plt.close("all")
def test_scalebar_axis( self, crystal_map_input, unit, expected_coordinate_axes, expected_width_px, expected_width_unit, expected_unit, ): cm = CrystalMap(**crystal_map_input) cm.scan_unit = unit assert cm._coordinate_axes == expected_coordinate_axes fig = plt.figure() ax = fig.add_subplot(projection=PLOT_MAP) _ = ax.plot_map(cm, scalebar=False) sbar = ax.add_scalebar(cm) # Scalebar width (_width attribute of Rectangle artist) assert np.allclose(sbar.size_bar._children[0]._width, expected_width_px, atol=1e-2) # Scalebar text if expected_unit == "um": expected_unit = "\u03BC" + "m" assert (sbar.txt_label._children[0]._text == f"{expected_width_unit} {expected_unit}") plt.close("all")
def test_orientations_none_symmetry_raises(self, crystal_map_input): cm = CrystalMap(**crystal_map_input) assert cm.phases.point_groups == [None] with pytest.raises(TypeError, match="'NoneType' object is not iterable"): _ = cm.orientations
def test_plot_phase(self, crystal_map_input, phase_list, expected_data_shape): cm = CrystalMap(**crystal_map_input) assert np.unique(cm.phase_id) == np.array([0]) # Test code assumption assert phase_list.ids == [0, 1, 2] cm.phases = phase_list cm[0, 0].phase_id = 0 cm[1, 1].phase_id = 2 fig = plt.figure() ax = fig.add_subplot(projection=PLOT_MAP) im = ax.plot_map(cm) # Expected image data phase_id = cm.get_map_data("phase_id") unique_phase_ids = np.unique(phase_id[~np.isnan(phase_id)]) expected_data = np.ones(phase_id.shape + (3, )) for i, color in zip(unique_phase_ids, cm.phases_in_data.colors_rgb): mask = phase_id == int(i) expected_data[mask] = expected_data[mask] * color image_data = im.get_array() assert np.allclose(image_data.shape, expected_data_shape) assert np.allclose(image_data, expected_data) plt.close("all")
def to_crystal_map(self): """ Exports an indexation result with multiple results per navigation position to crystal map with one result per pixel Returns ------- orix.CrystalMap """ _s = self.data.map(_get_best_match,inplace=False) """ Gets properties """ phase_id = _s.isig[0].data.flatten() alpha = _s.isig[1].data.flatten() beta = _s.isig[2].data.flatten() gamma = _s.isig[3].data.flatten() score = _s.isig[4].data.flatten() """ Gets navigation placements """ xy = np.indices(_s.data.shape[:2]) x = xy[1].flatten() y = xy[0].flatten() """ Tidies up so we can put these things into CrystalMap """ euler = np.vstack((alpha,beta,gamma)).T rotations = Rotation.from_euler(euler,convention="bunge", direction="crystal2lab") properties = {"score":score} return CrystalMap( rotations=rotations, phase_id=phase_id, x=x, y=y, prop=properties)
def test_get_orientation_similarity_map(self): s = nickel_ebsd_small() s_dict1 = EBSD(s.data.reshape(-1, 60, 60)) s_dict2 = EBSD(s.data.reshape(-1, 60, 60)) n_patterns = s_dict1.axes_manager.navigation_size s_dict1._xmap = CrystalMap(Rotation(np.zeros((n_patterns, 4)))) s_dict2._xmap = CrystalMap(Rotation(np.zeros((n_patterns, 4)))) s_dict1.xmap.phases[0].name = "a" s_dict2.xmap.phases[0].name = "b" sd = StaticPatternMatching([s_dict1, s_dict2]) res = sd(s, keep_n=1, get_orientation_similarity_map=True) xmap1, _ = res assert np.allclose(xmap1.scores, 1) assert np.all(["osm" in xmap.prop for xmap in res])
def test_init_map_with_props(self, crystal_map_input): x = crystal_map_input["x"] props = {"iq": np.arange(x.size)} cm = CrystalMap(prop=props, **crystal_map_input) assert cm.prop == props assert np.allclose(cm.prop.id, cm.id) assert np.allclose(cm.prop.is_in_data, cm.is_in_data)
def test_init_with_too_many_phases( self, crystal_map_input, phase_names, phase_ids, desired_phase_names ): """More phases than phase IDs.""" phase_list = PhaseList(names=phase_names, ids=phase_ids) xmap = CrystalMap(phase_list=phase_list, **crystal_map_input) assert xmap.phases.names == desired_phase_names
def test_orientation_similarity_map(self): xmap = CrystalMap( rotations=Rotation(np.zeros((100, 4))), prop={"simulation_indices": np.tile(np.arange(5), (100, 1))}, x=np.tile(np.arange(10), 10), y=np.tile(np.arange(10), 10), ) assert np.allclose(orientation_similarity_map(xmap), np.ones((10, 10)))
def test_getitem_with_masking(self, crystal_map_input): x = crystal_map_input["x"] props = {"iq": np.arange(x.size)} cm = CrystalMap(prop=props, **crystal_map_input) cm2 = cm[cm.iq > 1] assert np.allclose(cm2.prop.id, cm2.id) assert np.allclose(cm2.prop.is_in_data, cm2.is_in_data)
def test_n_best_too_great(self): xmap = CrystalMap( rotations=Rotation(np.zeros((100, 4))), prop={"simulation_indices": np.ones((100, 5))}, x=np.tile(np.arange(10), 10), y=np.tile(np.arange(10), 10), ) with pytest.raises(ValueError, match="n_best 6 cannot be greater than"): orientation_similarity_map(xmap, n_best=6)
def test_multiple_orientations_per_point( self, crystal_map_input, rotations_per_point ): cm = CrystalMap(**crystal_map_input) assert cm.phases.ids == [0] # Test code assumption cm.phases[0].point_group = "m-3m" assert cm.rotations_per_point == rotations_per_point assert cm.orientations.size == cm.size
def compute_refine_orientation_projection_center_results( results: list, detector, xmap: CrystalMap, master_pattern, ): """Compute the results from :meth:`~kikuchipy.signals.EBSD.refine_orientation_projection_center` and return the :class:`~orix.crystal_map.CrystalMap` and :class:`~kikuchipy.detectors.EBSDDetector`. Parameters ---------- results Results returned from `refine_orientation_projection_center()`, which is a list of :class:`~dask.delayed.Delayed`. detector : ~kikuchipy.detectors.EBSDDetector Detector passed to `refine_orientation_projection_center()` to obtain `results`. xmap Crystal map passed to `refine_orientation_projection_center()` to obtain `results`. master_pattern : ~kikuchipy.signals.EBSDMasterPattern Master pattern passed to `refine_orientation_projection_center()` to obtain `results`. Returns ------- xmap_refined : :class:`~orix.crystal_map.CrystalMap` Crystal map with refined orientations and scores. new_detector : :class:`~kikuchipy.detectors.EBSDDetector` EBSD detector with refined projection center parameters. """ n_patterns = len(results) nav_shape = xmap.shape with ProgressBar(): print( f"Refining {n_patterns} orientation(s) and projection center(s):", file=sys.stdout, ) computed_results = dask.compute(*results) computed_results = np.array(computed_results) # (n, score, phi1, Phi, phi2, PCx, PCy, PCz) xmap_refined = CrystalMap( rotations=Rotation.from_euler(computed_results[:, 1:4]), phase_id=np.zeros(n_patterns), x=xmap.x, y=xmap.y, phase_list=PhaseList(phases=master_pattern.phase), prop=dict(scores=computed_results[:, 0]), scan_unit=xmap.scan_unit, ) new_detector = detector.deepcopy() new_detector.pc = computed_results[:, 4:].reshape(nav_shape + (3, )) return xmap_refined, new_detector
def test_signal_varying_dimensions(self, dummy_signal, slices, desired_xmap_shape): s = dummy_signal.inav[slices] sig_shape = dummy_signal.axes_manager.signal_shape s_dict1 = EBSD(dummy_signal.data.reshape((-1, ) + sig_shape)) n_sim = s_dict1.axes_manager.navigation_size s_dict1._xmap = CrystalMap(Rotation(np.zeros((n_sim, 4)))) sd = StaticPatternMatching(s_dict1) res = sd(s) assert res.shape == desired_xmap_shape
def test_data_slice_from_coordinates_masked( self, crystal_map_input, slices, expected_size, expected_shape, expected_slices ): xmap = CrystalMap(**crystal_map_input) # Mask data xmap2 = xmap[slices] assert xmap2.size == expected_size assert xmap2.shape == expected_shape assert xmap2._data_slices_from_coordinates() == expected_slices
def test_orientations_symmetry(self, point_group, rotation, expected_orientation): r = Rotation(rotation) cm = CrystalMap(rotations=r, phase_id=np.array([0])) cm.phases = PhaseList(Phase("a", point_group=point_group)) o = cm.orientations assert np.allclose( o.data, Orientation(r).set_symmetry(point_group).data, atol=1e-3 ) assert np.allclose(o.data, expected_orientation, atol=1e-3)
def test_1d_map(self, crystal_map_input, tmp_path): xmap = CrystalMap(**crystal_map_input) assert xmap.ndim == 1 fname = tmp_path / "test_1d_map.ang" save(fname, xmap) xmap_reload = load(fname) assert xmap_reload.ndim == 1 assert np.allclose(xmap.rotations.to_euler(), xmap_reload.rotations.to_euler())
def to_crystal_map(self): """Obtain a crystallographic map specifying the best matching phase and orientation at each probe position with corresponding metrics. Raises ------- ValueError("Currently under development") """ raise ValueError("Currently under development") _s = self.map( crystal_from_vector_matching, inplace=False) """ Gets phase, the easy bit """ phase_id = _s.isig[0].data.flatten() """ Deals with the properties, hard coded as of v0.13 """ # need to invert an array of dicts into a dict of arrays def _map_to_get_property(prop): return d[prop] # assume same properties at every point of the signal key_list = [] for key in _s.inav[0,0].isig[2]: key_list.append(key) properties = {} for key in key_list: _key_signal = _s.isig[2].map(_map_to_get_property,prop=key,inplace=False) properties[key] = _key_signal """ Deal with the rotations """ def _map_for_alpha_beta_gamma(ix): return z[ix] alpha = _s.isig[1].map(_map_for_alpha_beta_gamma,ix=0,inplace=False) beta = _s.isig[1].map(_map_for_alpha_beta_gamma,ix=1,inplace=False) gamma = _s.isig[1].map(_map_for_alpha_beta_gamma,ix=2,inplace=False) euler = np.vstack((alpha,beta,gamma)).T rotations = Rotation.from_euler(euler,convention="bunge", direction="crystal2lab") """ Gets navigation placements """ xy = np.indices(_s.data.shape[:2]) x = xy[1].flatten() y = xy[0].flatten() return CrystalMap( rotations=rotations, phase_id=phase_id, x=x, y=y, prop=properties)
def test_keep_n(self, n_rot_in, n_rot_out, keep_n): s = nickel_ebsd_small() s_dict = EBSD(np.random.random((n_rot_in, 60, 60)).astype(np.float32)) s_dict._xmap = CrystalMap(Rotation(np.zeros((n_rot_in, 4)))) sd = StaticPatternMatching(s_dict) xmap = sd(s) assert xmap.rotations_per_point == n_rot_out xmap2 = sd(s, keep_n=keep_n) assert xmap2.rotations_per_point == keep_n
def test_get_by_condition(self, crystal_map_input): cm = CrystalMap(**crystal_map_input) cm.prop["dp"] = np.arange(cm.size) n_points = 2 assert cm.shape == (4, 3) # Test code assumption cm[0, :n_points].dp = -1 cm2 = cm[cm.dp < 0] assert cm2.size == n_points assert np.sum(cm2.dp) == -n_points
def test_crystalmap2dict(self, temp_file_path, crystal_map_input): cm = CrystalMap(**crystal_map_input) cm_dict = crystalmap2dict(cm) this_dict = {"hello": "there"} cm_dict2 = crystalmap2dict(cm, dictionary=this_dict) cm_dict2.pop("hello") assert_dictionaries_are_equal(cm_dict, cm_dict2) assert np.allclose(cm_dict["data"]["x"], crystal_map_input["x"]) assert cm_dict["header"]["z_step"] == cm.dz
def test_init_with_phase_id(self, crystal_map_input): phase_id = crystal_map_input["phase_id"] cm = CrystalMap(**crystal_map_input) assert np.allclose(cm.phase_id, phase_id) # Test all_indexed if -1 in np.unique(phase_id): assert not cm.all_indexed assert -1 in cm.phases.ids else: assert cm.all_indexed assert -1 not in cm.phases.ids
def test_write_read_masked(self, crystal_map_input, temp_file_path): cm = CrystalMap(**crystal_map_input) save(filename=temp_file_path, object2write=cm[cm.x > 2]) cm2 = load(temp_file_path) assert cm2.size != cm.size with pytest.raises(ValueError, match="operands could not be broadcast"): _ = np.allclose(cm2.x, cm.x) cm2.is_in_data = cm.is_in_data assert cm2.size == cm.size assert np.allclose(cm2.x, cm.x)
def test_from_n_best(self): sim_idx_prop = "simulated_indices" xmap = CrystalMap( rotations=Rotation(np.zeros((100, 4))), prop={sim_idx_prop: np.ones((100, 5))}, x=np.tile(np.arange(10), 10), y=np.tile(np.arange(10), 10), ) osm = orientation_similarity_map(xmap, simulation_indices_prop=sim_idx_prop, from_n_best=2) assert osm.shape == (10, 10, 4)
def test_scalebar_warns(self, crystal_map_input, warns): cm = CrystalMap(**crystal_map_input) fig = plt.figure() ax = fig.add_subplot(projection=PLOT_MAP) if warns: with pytest.warns(UserWarning, match=SCALEBAR_WARNING): _ = ax.plot_map(cm) else: _ = ax.plot_map(cm) plt.close("all")
def test_get_orientations_array(self, crystal_map_input, phase_list): cm = CrystalMap(**crystal_map_input) cm[:2, 0].phase_id = 1 # Test code assumption id1 = 0 id2 = 1 assert np.allclose(np.unique(cm.phase_id), np.array([id1, id2])) cm.phases = phase_list # Get all with string o = cm.get_map_data("orientations") # Get per phase with string cm1 = cm[cm.phase_id == id1] cm2 = cm[cm.phase_id == id2] o1 = cm1.get_map_data("orientations") o2 = cm2.get_map_data("orientations") expected_o1 = cm1.orientations.to_euler() expected_shape = expected_o1.shape assert np.allclose( o1[~np.isnan(o1)].reshape(expected_shape), expected_o1, atol=1e-3 ) expected_o2 = cm2.orientations.to_euler() expected_shape = expected_o2.shape assert np.allclose( o2[~np.isnan(o2)].reshape(expected_shape), expected_o2, atol=1e-3 ) # Do calculations "manually" data_shape = (cm.size, 3) array = np.zeros(data_shape) if cm.rotations_per_point > 1: rotations = cm.rotations[:, 0] else: rotations = cm.rotations for i, phase in cm.phases_in_data: phase_mask = cm._phase_id == i phase_mask_in_data = cm.phase_id == i array[phase_mask] = ( Orientation(rotations[phase_mask_in_data]) .set_symmetry(phase.point_group) .to_euler() ) assert np.allclose(o, array.reshape(o.shape), atol=1e-3)
def test_minimal_init(self, rotations): map_size = 2 assert isinstance(rotations, Rotation) cm = CrystalMap(rotations=rotations) assert np.allclose(cm.x, np.arange(map_size)) assert cm.size == map_size assert cm.shape == (map_size,) assert cm.ndim assert np.allclose(cm.id, np.arange(map_size)) assert isinstance(cm.rotations, Rotation) assert np.allclose(cm.rotations.data, rotations.data)