def test_multiprofile_of_two_maps_builds_two_line_profiles(self): with TestContext.create_memory_context() as test_context: document_controller = test_context.create_document_controller() document_model = document_controller.document_model elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(14, 1, 1)) # Si-K elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(32, 2, 3)) # Ge-L edge_bundle = elemental_mapping_controller.build_edge_bundles( document_controller) edge_bundle[0].map_action() self.__run_until_complete(document_controller) edge_bundle[1].map_action() self.__run_until_complete(document_controller) self.assertEqual(3, len(document_model.data_items)) elemental_mapping_controller.build_multiprofile( document_controller) self.assertEqual(5, len(document_model.data_items)) self.assertEqual(6, len(document_model.display_items)) composite_display_item = document_model.display_items[3] line_profile1_data_item = document_model.data_items[3] line_profile2_data_item = document_model.data_items[4] self.assertIn(line_profile1_data_item, composite_display_item.data_items) self.assertIn(line_profile2_data_item, composite_display_item.data_items)
def test_multiprofile_of_two_maps_builds_two_line_profiles(self): document_model = DocumentModel.DocumentModel() elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) document_controller = DocumentController.DocumentController( self.app.ui, document_model, workspace_id="library") with contextlib.closing(document_controller), contextlib.closing( elemental_mapping_controller): model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(14, 1, 1)) # Si-K elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(32, 2, 3)) # Ge-L edge_bundle = elemental_mapping_controller.build_edge_bundles( document_controller) edge_bundle[0].map_action() self.__run_until_complete(document_controller) edge_bundle[1].map_action() self.__run_until_complete(document_controller) self.assertEqual(3, len(document_model.data_items)) elemental_mapping_controller.build_multiprofile( document_controller) self.assertEqual(5, len(document_model.data_items)) self.assertEqual(6, len(document_model.display_items)) composite_display_item = document_model.display_items[3] line_profile1_data_item = document_model.data_items[3] line_profile2_data_item = document_model.data_items[4] self.assertIn(line_profile1_data_item, composite_display_item.data_items) self.assertIn(line_profile2_data_item, composite_display_item.data_items)
def test_multiprofile_of_two_maps_connects_line_profiles(self): with TestContext.create_memory_context() as test_context: document_controller = test_context.create_document_controller() document_model = document_controller.document_model elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(14, 1, 1)) # Si-K elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(32, 2, 3)) # Ge-L edge_bundle = elemental_mapping_controller.build_edge_bundles( document_controller) edge_bundle[0].map_action() self.__run_until_complete(document_controller) edge_bundle[1].map_action() self.__run_until_complete(document_controller) elemental_mapping_controller.build_multiprofile( document_controller) map1_display_item = document_model.get_display_item_for_data_item( document_model.data_items[1]) map2_display_item = document_model.get_display_item_for_data_item( document_model.data_items[2]) # composite_data_item = document_model.data_items[3] # line_profile1_data_item = document_model.data_items[4] # line_profile2_data_item = document_model.data_items[5] line_region1 = map1_display_item.graphics[0] line_region2 = map2_display_item.graphics[0] self.assertEqual(line_region1.vector, line_region2.vector) self.assertEqual(line_region1.width, line_region2.width) line_region1.vector = (0.11, 0.12), (0.21, 0.22) self.assertEqual(line_region1.vector, line_region2.vector) self.assertEqual(line_region1.width, line_region2.width)
def test_adding_multiple_edges(self): with TestContext.create_memory_context() as test_context: document_controller = test_context.create_document_controller() document_model = document_controller.document_model elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(32, 2, 3)) # Ge-L elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(14, 1, 1)) # Si-K self.assertEqual(2, len(document_model.data_structures))
def test_mapping_edge_produces_properly_configured_map(self): document_model = DocumentModel.DocumentModel() elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) document_controller = DocumentController.DocumentController( self.app.ui, document_model, workspace_id="library") with contextlib.closing(document_controller), contextlib.closing( elemental_mapping_controller): model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(14, 1, 1)) # Si-K edge_bundle = elemental_mapping_controller.build_edge_bundles( document_controller) edge_bundle[0].map_action() self.__run_until_complete(document_controller) self.assertEqual(2, len(document_model.data_items)) mapped_data_item = document_model.data_items[1] self.assertEqual(model_data_item, mapped_data_item.source) self.assertEqual(1, len(document_model.computations)) self.assertEqual("eels.mapping", document_model.computations[0].processing_id) self.assertEqual(mapped_data_item.dimensional_calibrations, model_data_item.dimensional_calibrations[0:2])
def test_deleting_pick_region_also_deletes_pick_composition(self): document_model = DocumentModel.DocumentModel() elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) document_controller = DocumentController.DocumentController( self.app.ui, document_model, workspace_id="library") with contextlib.closing(document_controller), contextlib.closing( elemental_mapping_controller): model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) model_display_item = document_model.get_display_item_for_data_item( model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(14, 1, 1)) # Si-K edge_bundle = elemental_mapping_controller.build_edge_bundles( document_controller) edge_bundle[0].pick_action() self.__run_until_complete(document_controller) pick_region = model_display_item.graphics[0] eels_data_item = document_model.data_items[1] self.assertEqual(1, len(document_model.computations)) self.assertEqual(2, len(document_model.data_items)) self.assertEqual(2, len(document_model.data_structures)) model_display_item.remove_graphic(pick_region) self.assertEqual(0, len(document_model.computations)) self.assertEqual(1, len(document_model.data_items)) self.assertEqual(1, len(document_model.data_structures))
def test_picking_edge_produces_properly_configured_composite(self): with TestContext.create_memory_context() as test_context: document_controller = test_context.create_document_controller() document_model = document_controller.document_model elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) model_display_item = document_model.get_display_item_for_data_item( model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(14, 1, 1)) # Si-K edge_bundle = elemental_mapping_controller.build_edge_bundles( document_controller) edge_bundle[0].pick_action() self.__run_until_complete(document_controller) self.assertEqual(2, len(document_model.data_items)) eels_data_item = document_model.data_items[1] self.assertEqual(model_display_item.graphics[0], eels_data_item.source) self.assertEqual(eels_data_item, document_model.data_structures[1].source) self.assertEqual("elemental_mapping_edge_ref", document_model.data_structures[1].structure_type) self.assertEqual( document_model.data_structures[0], document_model.data_structures[1].get_referenced_object( "edge"))
def test_adding_multiple_edges(self): document_model = DocumentModel.DocumentModel() elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) document_controller = DocumentController.DocumentController( self.app.ui, document_model, workspace_id="library") with contextlib.closing(document_controller), contextlib.closing( elemental_mapping_controller): model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(32, 2, 3)) # Ge-L elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(14, 1, 1)) # Si-K self.assertEqual(2, len(document_model.data_structures))
def test_deleting_pick_region_also_deletes_pick_composition(self): with TestContext.create_memory_context() as test_context: document_controller = test_context.create_document_controller() document_model = document_controller.document_model elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) model_display_item = document_model.get_display_item_for_data_item( model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(14, 1, 1)) # Si-K edge_bundle = elemental_mapping_controller.build_edge_bundles( document_controller) edge_bundle[0].pick_action() self.__run_until_complete(document_controller) pick_region = model_display_item.graphics[0] eels_data_item = document_model.data_items[1] self.assertEqual(1, len(document_model.computations)) self.assertEqual(2, len(document_model.data_items)) self.assertEqual(2, len(document_model.data_structures)) model_display_item.remove_graphic(pick_region) self.assertEqual(0, len(document_model.computations)) self.assertEqual(1, len(document_model.data_items)) self.assertEqual(1, len(document_model.data_structures))
def read(self, data_structure) -> None: atomic_number = data_structure.get_property_value("atomic_number") shell_number = data_structure.get_property_value("shell_number") subshell_index = data_structure.get_property_value("subshell_index") self.__electron_shell = PeriodicTable.ElectronShell(atomic_number, shell_number, subshell_index) self.__fit_interval = data_structure.get_property_value("fit_interval", (0.4, 0.5)) self.__signal_interval = data_structure.get_property_value("signal_interval", (0.5, 0.6))
def __create_edge(self, model_data_item: DataItem.DataItem, electron_shell: PeriodicTable.ElectronShell): binding_energy_eV = PeriodicTable.PeriodicTable( ).nominal_binding_energy_ev(electron_shell) signal_interval_eV = binding_energy_eV, binding_energy_eV * 1.10 fit_interval_eV = binding_energy_eV * 0.93, binding_energy_eV * 0.98 dimensional_shape = model_data_item.dimensional_shape dimensional_calibrations = model_data_item.dimensional_calibrations if dimensional_shape is not None and dimensional_calibrations is not None and len( dimensional_calibrations) > 0: calibration = dimensional_calibrations[-1] if calibration.units == "eV": fit_region_start = calibration.convert_from_calibrated_value( fit_interval_eV[0]) / dimensional_shape[-1] fit_region_end = calibration.convert_from_calibrated_value( fit_interval_eV[1]) / dimensional_shape[-1] signal_region_start = calibration.convert_from_calibrated_value( signal_interval_eV[0]) / dimensional_shape[-1] signal_region_end = calibration.convert_from_calibrated_value( signal_interval_eV[1]) / dimensional_shape[-1] fit_interval = fit_region_start, fit_region_end signal_interval = signal_region_start, signal_region_end return ElementalMappingController.ElementalMappingEdge( electron_shell=electron_shell, fit_interval=fit_interval, signal_interval=signal_interval) return None
def test_subshell_label(self): # Test all possible labels up to f-states subshell_labels = [None, "s", "p", "p", "d", "d", "f", "f"] spin_numerators = [None, 1, 1, 3, 3, 5, 5, 7] for subshell_index in range(len(subshell_labels))[1:]: electron_shell = PeriodicTable.ElectronShell(99, 4, subshell_index) self.assertEqual(electron_shell.subshell_label, subshell_labels[subshell_index]) self.assertEqual(electron_shell.spin_fraction, fractions.Fraction(spin_numerators[subshell_index], 2))
def execute(self, **kwargs): spectrum_image_xdata = kwargs["spectrum_image_xdata"] fit_interval = kwargs["fit_interval"] signal_interval = kwargs["signal_interval"] atomic_number = kwargs.get("atomic_number") shell_number = kwargs.get("shell_number") subshell_index = kwargs.get("subshell_index") electron_shell = None if atomic_number is not None and shell_number is not None and subshell_index is not None: electron_shell = PeriodicTable.ElectronShell(atomic_number, shell_number, subshell_index) self.__mapped_xdata = eels_analysis.map_background_subtracted_signal(spectrum_image_xdata, electron_shell, [fit_interval], signal_interval)
def test_removing_edges(self): with TestContext.create_memory_context() as test_context: document_controller = test_context.create_document_controller() document_model = document_controller.document_model elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) ge_edge = elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(32, 2, 3)) # Ge-L si_edge = elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(14, 1, 1)) # Si-K self.assertEqual(2, len(document_model.data_structures)) elemental_mapping_controller.remove_edge(ge_edge) self.assertEqual(1, len(document_model.data_structures)) self.assertEqual( 14, document_model.data_structures[0].get_property_value( "atomic_number")) elemental_mapping_controller.remove_edge(si_edge) self.assertEqual(0, len(document_model.data_structures))
def test_removing_edges(self): document_model = DocumentModel.DocumentModel() elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) document_controller = DocumentController.DocumentController( self.app.ui, document_model, workspace_id="library") with contextlib.closing(document_controller), contextlib.closing( elemental_mapping_controller): model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) ge_edge = elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(32, 2, 3)) # Ge-L si_edge = elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(14, 1, 1)) # Si-K self.assertEqual(2, len(document_model.data_structures)) elemental_mapping_controller.remove_edge(ge_edge) self.assertEqual(1, len(document_model.data_structures)) self.assertEqual( 14, document_model.data_structures[0].get_property_value( "atomic_number")) elemental_mapping_controller.remove_edge(si_edge) self.assertEqual(0, len(document_model.data_structures))
def test_explore_adds_edge(self): with TestContext.create_memory_context() as test_context: document_controller = test_context.create_document_controller() document_model = document_controller.document_model elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) document_controller.event_loop.create_task( elemental_mapping_controller.explore_edges( document_controller)) document_controller.periodic() # start tasks document_model.recompute_all() document_controller.periodic() # finish tasks explorer_data_item = document_model.data_items[1] explorer_display_item = document_model.get_display_item_for_data_item( explorer_data_item) elemental_mapping_controller.set_current_data_item( explorer_data_item) self.assertIsNotNone(elemental_mapping_controller.model_data_item) energy_calibration = explorer_data_item.dimensional_calibrations[ -1] explorer_display_item.graphics[ -1].interval = energy_calibration.convert_from_calibrated_value( 1200 ) / 1024, energy_calibration.convert_from_calibrated_value( 1226) / 1024 for _ in range(3): # there is something funny about how async works; recent versions of Swift are faster # and have revealed some race condition about how items get added to the async queue. # to avoid that problem, do periodic over a period of a few ms. document_controller.periodic() # update explorer interval time.sleep(0.01) edges = PeriodicTable.PeriodicTable( ).find_edges_in_energy_interval( elemental_mapping_controller.explorer_interval) elemental_mapping_controller.add_edge(edges[0]) self.assertEqual(1, len(document_model.data_structures)) edge_data_struct = document_model.data_structures[0] self.assertEqual("elemental_mapping_edge", edge_data_struct.structure_type) self.assertEqual(model_data_item, edge_data_struct.source) self.assertEqual( 32, edge_data_struct.get_property_value("atomic_number")) self.assertEqual( 2, edge_data_struct.get_property_value("shell_number")) self.assertEqual( 3, edge_data_struct.get_property_value("subshell_index"))
def test_explore_adds_edge(self): document_model = DocumentModel.DocumentModel() elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) document_controller = DocumentController.DocumentController( self.app.ui, document_model, workspace_id="library") with contextlib.closing(document_controller), contextlib.closing( elemental_mapping_controller): model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) document_controller.event_loop.create_task( elemental_mapping_controller.explore_edges( document_controller)) document_controller.periodic() # start tasks document_model.recompute_all() document_controller.periodic() # finish tasks explorer_data_item = document_model.data_items[1] explorer_display_item = document_model.get_display_item_for_data_item( explorer_data_item) elemental_mapping_controller.set_current_data_item( explorer_data_item) self.assertIsNotNone(elemental_mapping_controller.model_data_item) energy_calibration = explorer_data_item.dimensional_calibrations[ -1] explorer_display_item.graphics[ -1].interval = energy_calibration.convert_from_calibrated_value( 1200 ) / 1024, energy_calibration.convert_from_calibrated_value( 1226) / 1024 document_controller.periodic() # update explorer interval edges = PeriodicTable.PeriodicTable( ).find_edges_in_energy_interval( elemental_mapping_controller.explorer_interval) elemental_mapping_controller.add_edge(edges[0]) self.assertEqual(1, len(document_model.data_structures)) edge_data_struct = document_model.data_structures[0] self.assertEqual("elemental_mapping_edge", edge_data_struct.structure_type) self.assertEqual(model_data_item, edge_data_struct.source) self.assertEqual( 32, edge_data_struct.get_property_value("atomic_number")) self.assertEqual( 2, edge_data_struct.get_property_value("shell_number")) self.assertEqual( 3, edge_data_struct.get_property_value("subshell_index"))
def test_map_background_subtracted_signal_produces_correct_calibrations( self): calibration = Calibration.Calibration(200.0, 2.0, 'eV') calibration_y = Calibration.Calibration(101.0, 1.5, 'nm') calibration_x = Calibration.Calibration(102.0, 2.5, 'nm') spectrum_length = 1000 w, h = 20, 20 electron_shell = PeriodicTable.ElectronShell(1, 1, 0) data_and_metadata = DataAndMetadata.DataAndMetadata.from_data( numpy.ones((spectrum_length, w, h), numpy.float), dimensional_calibrations=[ calibration_y, calibration_x, calibration ]) mapped = eels_analysis.map_background_subtracted_signal( data_and_metadata, electron_shell, [(0.2, 0.3)], (0.4, 0.5)) self.assertEqual(len(mapped.dimensional_shape), 2) self.assertEqual(len(mapped.dimensional_calibrations), 2) self.assertEqual(mapped.dimensional_calibrations[0], calibration_y) self.assertEqual(mapped.dimensional_calibrations[1], calibration_x)
def test_find_edges_in_interval_single_atom(self): # This tests the new functionality, which allows for filtering by a single atom. ptable = PeriodicTable.PeriodicTable() edges = ptable.find_all_edges_in_energy_interval((450.0, 470.0), 22) # In this interval there should be 7 edges: Ti L2, Ti L3, Nb M1, Ru M3, In M4, Ta N2, and Bi N4 assert len(edges) == 2 atomic_numbers = {edge.atomic_number for edge in edges} assert atomic_numbers == {22} shell_numbers = {edge.shell_number for edge in edges} assert shell_numbers == {2} subshell_indices = {edge.subshell_index for edge in edges} assert subshell_indices == {2, 3} shell_strings = { edge.get_shell_str_in_eels_notation(True) for edge in edges } assert shell_strings == {"L2", "L3"} binding_energies = { ptable.nominal_binding_energy_ev(edge) for edge in edges } assert binding_energies == {453.8, 460.2}
def test_selecting_composite_updates_edge_value(self): with TestContext.create_memory_context() as test_context: document_controller = test_context.create_document_controller() document_model = document_controller.document_model elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) si_edge = elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(14, 1, 1)) # Si-K edge_bundle = elemental_mapping_controller.build_edge_bundles( document_controller) edge_bundle[0].pick_action() self.__run_until_complete(document_controller) self.assertIsNone(elemental_mapping_controller.edge) eels_data_item = document_model.data_items[1] elemental_mapping_controller.set_current_data_item(eels_data_item) self.assertEqual(model_data_item, elemental_mapping_controller.model_data_item) self.assertEqual(si_edge.data_structure, elemental_mapping_controller.edge.data_structure)
def test_controller_has_proper_edge_bundles_when_explorer_selected(self): with TestContext.create_memory_context() as test_context: document_controller = test_context.create_document_controller() document_model = document_controller.document_model elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(14, 1, 1)) # Si-K document_controller.event_loop.create_task( elemental_mapping_controller.explore_edges( document_controller)) self.__run_until_complete(document_controller) explorer_data_item = document_model.data_items[1] elemental_mapping_controller.set_current_data_item( explorer_data_item) self.assertIsNotNone(elemental_mapping_controller.model_data_item) edge_bundle = elemental_mapping_controller.build_edge_bundles( document_controller) self.assertEqual(1, len(edge_bundle))
def test_background_subtraction_computation_functions_reasonably(self): document_model = DocumentModel.DocumentModel() self.app._set_document_model( document_model) # required to allow API to find document model elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) document_controller = DocumentController.DocumentController( self.app.ui, document_model, workspace_id="library") with contextlib.closing(document_controller), contextlib.closing( elemental_mapping_controller): model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) si_edge = elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(14, 1, 1)) # Si-K spectrum_data_item = self.__create_spectrum() document_model.append_data_item(spectrum_data_item) spectrum_display_item = document_model.get_display_item_for_data_item( spectrum_data_item) spectrum_display_data_channel = spectrum_display_item.get_display_data_channel_for_data_item( spectrum_data_item) computation = document_model.create_computation() computation.create_object( "eels_spectrum_xdata", document_model.get_object_specifier( spectrum_display_data_channel, "display_xdata")) computation.create_input( "fit_interval", document_model.get_object_specifier(si_edge.data_structure), "fit_interval") computation.create_input( "signal_interval", document_model.get_object_specifier(si_edge.data_structure), "signal_interval") computation.processing_id = "eels.background_subtraction" document_model.append_computation(computation) document_model.recompute_all() document_controller.periodic() self.assertEqual(2, len(document_model.data_items))
def update_add_buttons(): col1.remove_all() col2.remove_all() explore_interval = self.__elemental_mapping_controller.explorer_interval if explore_interval is not None: edges = PeriodicTable.PeriodicTable( ).find_edges_in_energy_interval(explore_interval) for i, edge in enumerate(edges[0:4]): button = ui.create_push_button_widget( edge.to_long_str()) def add_edge(model_data_item, edge, data_item): self.__elemental_mapping_controller.add_edge( edge) data_item_changed(model_data_item) data_item_changed(data_item) button.on_clicked = functools.partial( add_edge, model_data_item, edge, data_item) col = col1 if i % 2 == 0 else col2 col.add(button) col1.add_stretch() col2.add_stretch()
def test_mapping_edge_produces_properly_configured_map(self): with TestContext.create_memory_context() as test_context: document_controller = test_context.create_document_controller() document_model = document_controller.document_model elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(14, 1, 1)) # Si-K edge_bundle = elemental_mapping_controller.build_edge_bundles( document_controller) edge_bundle[0].map_action() self.__run_until_complete(document_controller) self.assertEqual(2, len(document_model.data_items)) mapped_data_item = document_model.data_items[1] self.assertEqual(model_data_item, mapped_data_item.source) self.assertEqual(1, len(document_model.computations)) self.assertEqual("eels.mapping", document_model.computations[0].processing_id) self.assertEqual(mapped_data_item.dimensional_calibrations, model_data_item.dimensional_calibrations[0:2])
def test_find_edges_in_interval(self): # This test fails in the old version of find_energies_in_interval. Finds only Ti L3 edge. ptable = PeriodicTable.PeriodicTable() edges = ptable.find_all_edges_in_energy_interval((450.0, 470.0)) # In this interval there should be 7 edges: Ti L2, Ti L3, Nb M1, Ru M3, In M4, Ta N2, and Bi N4 assert len(edges) == 7 atomic_numbers = {edge.atomic_number for edge in edges} assert atomic_numbers == {22, 41, 44, 49, 73, 83} shell_numbers = {edge.shell_number for edge in edges} assert shell_numbers == {2, 3, 4} subshell_indices = {edge.subshell_index for edge in edges} assert subshell_indices == {1, 2, 3, 4} shell_strings = { edge.get_shell_str_in_eels_notation(True) for edge in edges } assert shell_strings == {"L2", "L3", "M1", "M3", "M4", "N2", "N4"} binding_energies = { ptable.nominal_binding_energy_ev(edge) for edge in edges } assert binding_energies == { 453.8, 460.2, 466.6, 461.4, 451.4, 463.4, 464.0 }
def test_background_subtraction_computation_functions_reasonably(self): with TestContext.create_memory_context() as test_context: document_controller = test_context.create_document_controller_with_application( ) document_model = document_controller.document_model elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) si_edge = elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(14, 1, 1)) # Si-K spectrum_data_item = self.__create_spectrum() document_model.append_data_item(spectrum_data_item) spectrum_display_item = document_model.get_display_item_for_data_item( spectrum_data_item) spectrum_display_data_channel = spectrum_display_item.get_display_data_channel_for_data_item( spectrum_data_item) computation = document_model.create_computation() computation.create_input_item( "eels_spectrum_xdata", Symbolic.make_item(spectrum_display_data_channel, type="display_xdata")) computation.create_input_item("fit_interval", Symbolic.make_item( si_edge.data_structure), property_name="fit_interval") computation.create_input_item("signal_interval", Symbolic.make_item( si_edge.data_structure), property_name="signal_interval") computation.processing_id = "eels.background_subtraction" document_model.append_computation(computation) document_model.recompute_all() document_controller.periodic() self.assertEqual(2, len(document_model.data_items))
def test_controller_has_proper_edge_bundles_when_explorer_selected(self): document_model = DocumentModel.DocumentModel() elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) document_controller = DocumentController.DocumentController( self.app.ui, document_model, workspace_id="library") with contextlib.closing(document_controller), contextlib.closing( elemental_mapping_controller): model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(14, 1, 1)) # Si-K document_controller.event_loop.create_task( elemental_mapping_controller.explore_edges( document_controller)) self.__run_until_complete(document_controller) explorer_data_item = document_model.data_items[1] elemental_mapping_controller.set_current_data_item( explorer_data_item) self.assertIsNotNone(elemental_mapping_controller.model_data_item) edge_bundle = elemental_mapping_controller.build_edge_bundles( document_controller) self.assertEqual(1, len(edge_bundle))
def test_selecting_composite_updates_edge_value(self): document_model = DocumentModel.DocumentModel() elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) document_controller = DocumentController.DocumentController( self.app.ui, document_model, workspace_id="library") with contextlib.closing(document_controller), contextlib.closing( elemental_mapping_controller): model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) si_edge = elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(14, 1, 1)) # Si-K edge_bundle = elemental_mapping_controller.build_edge_bundles( document_controller) edge_bundle[0].pick_action() self.__run_until_complete(document_controller) self.assertIsNone(elemental_mapping_controller.edge) eels_data_item = document_model.data_items[1] elemental_mapping_controller.set_current_data_item(eels_data_item) self.assertEqual(model_data_item, elemental_mapping_controller.model_data_item) self.assertEqual(si_edge.data_structure, elemental_mapping_controller.edge.data_structure)
def test_eels_quantification(self): if True: # For now turn this test off. I will keep the directory of all EELS Atlas data on hand for more testing. return import glob import pandas df = pandas.read_csv("EELS_Atlas_Major/files_HE.dat", delim_whitespace=True, header=None) file_names, tmp1, efin, tmp2, estart = df.to_numpy().T i_search = 0 total_extra_found = 0 total_edges_edb = 0 total_edges_matched = 0 mintol = 0.1 nfail = 0 ntot = 0 ptable = PeriodicTable.PeriodicTable() for file_name in file_names: # Load data from text file. #data_file = glob.glob('./EELS_Atlas_Major/**/' + file_name,recursive = True)[0] print('\n\n\n') data_file = glob.glob('./EELS_Atlas_Major/**/' + file_name, recursive=True)[0] #edge_file = glob.glob('./EELS_Atlas_Major/**/' + 'edges_' + os.path.splitext(file_name)[0]+'.dat', recursive=True)[0] edge_file = glob.glob('./EELS_Atlas_Major/**/' + 'edges_' + os.path.splitext(file_name)[0] + '.dat', recursive=True)[0] energies, eels_spectrum = numpy.loadtxt(data_file, delimiter=',', unpack=True) energy_step = (energies[-1] - energies[0]) / energies.size energy_range_ev = numpy.array( [energies[0], energies[-1] + energy_step]) if estart[i_search] < 0: estart[i_search] = tmp1[i_search] search_range = [estart[i_search], efin[i_search]] chem_formula = file_name.split('_')[0] elements_exp = [ elem.strip(string.digits) for elem in re.findall('[A-Z][^A-Z]*', chem_formula) if str(ptable.atomic_number(elem.strip(string.digits))) in ptable.find_elements_in_energy_interval(search_range) ] print(file_name, ':') experimental_edge_data = EELS_DataAnalysis.find_experimental_edge_energies( eels_spectrum, energy_range_ev, search_range, debug_plotting=False) df = pandas.read_csv(edge_file, delim_whitespace=True, header=None) edge_data = EELS_DataAnalysis.find_species_from_experimental_edge_data( eels_spectrum, energy_range_ev, experimental_edge_data, search_range_ev=search_range, only_major_edges=True) elements_found = [ed[0] for ed in edge_data] edge_data = EELS_DataAnalysis.find_species_from_experimental_edge_data( eels_spectrum, energy_range_ev, experimental_edge_data, search_range_ev=search_range, only_major_edges=False, element_list=elements_found) edge_energies = experimental_edge_data[0] # Print edges found, and edges found by visual inspection for comparison. # The edge finder will not find all edges necessarily, and might find extra edges. elements_found = [ptable.element_symbol(ed[0]) for ed in edge_data] ntot += 1 if (all(x in elements_found for x in elements_exp)): missing = False else: print(chem_formula, ": Failed to find all elements") i_search += 1 continue edge_data = [ ed for ed in edge_data if ptable.element_symbol(ed[0]) in elements_exp ] #print('edge_data', edge_data) i_search += 1 # We now have the elements and the edges we want to analyze, lets do the quantification # Set microscope parameters beam_energy_keV = 200.0 convergence_angle_mrad = 0.0 collection_angle_mrad = 100.0 # Set up the atomic numbers, edge onsets, and background ranges atomic_numbers = [] background_ranges = [] edge_onsets = [] edge_deltas = [] iElement = 0 for ed in edge_data: iEdge = 0 edge_onset = [] while iEdge < len(ed[1]): edge_onsets = edge_onsets + [ed[1][iEdge][2]] atomic_numbers = atomic_numbers + [ed[0]] iEdge += 1 #print('Atoms in system:', atomic_numbers) deltas = 30.0 for i, onset in enumerate(edge_onsets): if i + 1 < len(edge_onsets) and atomic_numbers[ i] == atomic_numbers[i + 1]: if edge_onsets[i + 1] - onset > deltas: edge_deltas = edge_deltas + [deltas] else: edge_deltas = edge_deltas + [ deltas ] #[edge_onsets[i+1] - onset] #print(edge_deltas[-1]) else: edge_deltas = edge_deltas + [ min(deltas, energy_range_ev[1] - onset) ] if i > 0: if atomic_numbers[i] == atomic_numbers[i - 1]: #background_ranges = background_ranges + [numpy.array([max(onset - 30.0,edge_onsets[i-1]), onset - 10.0])] background_ranges = background_ranges + [ numpy.array([ max(onset - 30.0, energy_range_ev[0]), onset - 10.0 ]) ] else: background_ranges = background_ranges + [ numpy.array([ max(onset - 30.0, energy_range_ev[0]), onset - 10.0 ]) ] else: background_ranges = background_ranges + [ numpy.array([ max(onset - 30.0, energy_range_ev[0]), onset - 10.0 ]) ] #print(edge_onsets) #print(edge_deltas) #print(background_ranges) stoich, error_in_stoich, quant_data, diff_cross, egrid_ev = EELS_DataAnalysis.stoichiometry_from_eels( eels_spectrum, energy_range_ev, background_ranges, atomic_numbers, edge_onsets, edge_deltas, beam_energy_keV * 1000.0, convergence_angle_mrad / 1000.0, collection_angle_mrad / 1000.0) for iat, atm in enumerate(atomic_numbers): erange = (edge_onsets[iat] - 50.0, edge_onsets[iat] + edge_deltas[iat] + 50) edges = ptable.find_all_edges_in_energy_interval(erange, atm) print(ptable.element_symbol(atm), ':') print('Energy Range: ', edge_onsets[iat], edge_onsets[iat] + edge_deltas[iat]) for edg in edges: edgestr = edg.get_shell_str_in_eels_notation( include_subshell=True) print('\t', edgestr) print('\t', stoich[iat], error_in_stoich[iat]) print('\n\n###############################################') if False: import matplotlib.pyplot as plt e_step = (quant_data[iat][4][1] - quant_data[iat][4][0] ) / quant_data[iat][1][0].size profile_grid = numpy.arange(quant_data[iat][4][0], quant_data[iat][4][1], e_step) plt.plot(profile_grid, quant_data[iat][1][0]) plt.plot(profile_grid, quant_data[iat][3][0]) plt.plot(energies, eels_spectrum) plt.xlim(quant_data[iat][4][0] - 50, quant_data[iat][4][1] + 50) plt.plot(egrid_ev[iat], diff_cross[iat]) plt.show()
def test_changing_edge_configures_other_items_correctly(self): with TestContext.create_memory_context() as test_context: document_controller = test_context.create_document_controller() document_model = document_controller.document_model elemental_mapping_controller = ElementalMappingController.ElementalMappingController( document_model) model_data_item = self.__create_spectrum_image() document_model.append_data_item(model_data_item) model_display_item = document_model.get_display_item_for_data_item( model_data_item) elemental_mapping_controller.set_current_data_item(model_data_item) elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(14, 1, 1)) # Si-K elemental_mapping_controller.add_edge( PeriodicTable.ElectronShell(32, 2, 3)) # Ge-L edge_bundle = elemental_mapping_controller.build_edge_bundles( document_controller) edge_bundle[0].pick_action() self.__run_until_complete(document_controller) eels_data_item = document_model.data_items[1] eels_display_item = document_model.get_display_item_for_data_item( eels_data_item) elemental_mapping_controller.set_current_data_item(eels_data_item) edge_bundle = elemental_mapping_controller.build_edge_bundles( document_controller) # apply the change to the other edge edge_bundle[1].select_action() self.__run_until_complete(document_controller) computation = document_model.computations[0] old_edge_data_structure = document_model.data_structures[0] new_edge_data_structure = document_model.data_structures[1] edge_ref_data_structure = document_model.data_structures[2] pick_region = model_display_item.graphics[0] # check the titles self.assertEqual("Pick Ge-L3", pick_region.label) self.assertEqual("Pick Ge-L3 EELS Data of Untitled", eels_data_item.title) # check the old intervals are disconnected and the new are connected old_fit_interval = eels_display_item.graphics[0].interval old_signal_interval = eels_display_item.graphics[1].interval new_fit_interval = (0.6, 0.7) new_signal_interval = (0.7, 0.8) # ensure changing old edge doesn't affect any connections old_edge_data_structure.set_property_value("fit_interval", new_fit_interval) old_edge_data_structure.set_property_value("signal_interval", new_signal_interval) self.assertEqual(old_fit_interval, eels_display_item.graphics[0].interval) self.assertEqual(old_signal_interval, eels_display_item.graphics[1].interval) self.assertEqual(old_fit_interval, computation.get_input("fit_interval")) self.assertEqual(old_signal_interval, computation.get_input("signal_interval")) # ensure changing new edge affects all connections new_edge_data_structure.set_property_value("fit_interval", new_fit_interval) new_edge_data_structure.set_property_value("signal_interval", new_signal_interval) self.assertEqual(new_fit_interval, eels_display_item.graphics[0].interval) self.assertEqual(new_signal_interval, eels_display_item.graphics[1].interval) self.assertEqual(new_fit_interval, computation.get_input("fit_interval")) self.assertEqual(new_signal_interval, computation.get_input("signal_interval")) # and the edge reference self.assertEqual( new_edge_data_structure, edge_ref_data_structure.get_referenced_object("edge"))