async def map_new_edge(document_controller, model_data_item, edge) -> None: document_model = document_controller.document_model project = document_model.get_project_for_item(model_data_item) map_data_item = DataItem.new_data_item() map_data_item.title = "{} of {}".format(_("Map"), str(edge.electron_shell)) map_data_item.category = model_data_item.category map_data_item.source = model_data_item document_model.append_data_item(map_data_item, project=project) computation = document_model.create_computation() computation.source = map_data_item computation.create_input_item( "spectrum_image_xdata", Symbolic.make_item(model_data_item, type="xdata")) computation.create_input_item("fit_interval", Symbolic.make_item(edge.data_structure), property_name="fit_interval") computation.create_input_item("signal_interval", Symbolic.make_item(edge.data_structure), property_name="signal_interval") computation.processing_id = "eels.mapping" computation.create_output_item("map", Symbolic.make_item(map_data_item)) document_model.append_computation(computation, project=project) await document_model.compute_immediate(document_controller.event_loop, computation) map_display_item = document_model.get_display_item_for_data_item( map_data_item) document_controller.show_display_item(map_display_item)
def test_variables_get_updates_when_switching_data_items(self): with TestContext.create_memory_context() as test_context: document_controller = test_context.create_document_controller() document_model = document_controller.document_model data_item1 = DataItem.DataItem(numpy.zeros((10, 10))) document_model.append_data_item(data_item1) data_item2 = DataItem.DataItem(numpy.zeros((10, 10))) document_model.append_data_item(data_item2) computation = document_model.create_computation( "target.xdata = a.xdata + x") computation.create_input_item("a", Symbolic.make_item(data_item1)) computation.create_variable("x", value_type="integral", value=5) document_model.set_data_item_computation(data_item2, computation) panel1 = ComputationPanel.EditComputationDialog( document_controller, data_item1) with contextlib.closing(panel1): document_controller.periodic() # execute queue self.assertEqual(len(panel1._sections_for_testing), 0) panel2 = ComputationPanel.EditComputationDialog( document_controller, data_item2) with contextlib.closing(panel2): document_controller.periodic() # execute queue self.assertEqual(len(panel2._sections_for_testing), 2) document_controller.periodic() # execute queue self.assertEqual(len(panel1._sections_for_testing), 0)
def test_data_item_setting_slice_validates_when_data_changes(self): document_model = DocumentModel.DocumentModel() document_controller = DocumentController.DocumentController( self.app.ui, document_model, workspace_id="library") with contextlib.closing(document_controller): d = numpy.random.randn(4, 4, 12) data_item = DataItem.DataItem(d) document_model.append_data_item(data_item) map = {"a": Symbolic.make_item(data_item)} data_item2 = document_controller.processing_computation( "target.xdata = a.xdata[:,:,0:8]", map) document_model.recompute_all() assert numpy.array_equal(data_item2.data, d[:, :, 0:8]) display_item = document_model.get_display_item_for_data_item( data_item2) display_data_channel = display_item.display_data_channels[0] display_data_channel.slice_center = 6 display_data_channel.slice_width = 4 self.assertEqual(display_data_channel.slice_center, 6) self.assertEqual(display_data_channel.slice_width, 4) document_model.get_data_item_computation( display_item.data_item ).expression = "target.xdata = a.xdata[:, :, 0:4]" document_model.recompute_all() self.assertEqual(display_data_channel.slice_center, 3) self.assertEqual(display_data_channel.slice_width, 2)
def test_invalid_expression_shows_error_and_clears_it(self): document_model = DocumentModel.DocumentModel() document_controller = DocumentController.DocumentController(self.app.ui, document_model, workspace_id="library") with contextlib.closing(document_controller): data_item1 = DataItem.DataItem(numpy.zeros((10, 10))) document_model.append_data_item(data_item1) data_item2 = DataItem.DataItem(numpy.zeros((10, 10))) document_model.append_data_item(data_item2) computation = document_model.create_computation("target.xdata = -a.xdata") computation.create_input_item("a", Symbolic.make_item(data_item1)) document_model.set_data_item_computation(data_item2, computation) panel = ComputationPanel.EditComputationDialog(document_controller, data_item2) document_controller.periodic() # let the inspector see the computation document_controller.periodic() # and update the computation expression = panel._text_edit_for_testing.text self.assertFalse(panel._error_label_for_testing.text.strip()) panel._text_edit_for_testing.text = "target.xdata = xyz(a.xdata)" panel._update_button.on_clicked() # the sequence of periodic/recompute_all is intentional, to test various computation states document_controller.periodic() document_model.recompute_all() document_model.recompute_all() document_controller.periodic() self.assertEqual(panel._text_edit_for_testing.text, "target.xdata = xyz(a.xdata)") self.assertTrue(len(panel._error_label_for_testing.text) > 0) panel._text_edit_for_testing.text = expression panel._update_button.on_clicked() # the sequence of periodic/recompute_all is intentional, to test various computation states document_controller.periodic() document_model.recompute_all() document_model.recompute_all() document_controller.periodic() self.assertEqual(panel._text_edit_for_testing.text, expression) self.assertIsNone(panel._error_label_for_testing.text)
def test_data_item_setting_slice_validates_when_data_changes(self): with TestContext.create_memory_context() as test_context: document_controller = test_context.create_document_controller() document_model = document_controller.document_model d = numpy.random.randn(4, 4, 12) data_item = DataItem.DataItem(d) document_model.append_data_item(data_item) map = {"a": Symbolic.make_item(data_item)} data_item2 = document_controller.processing_computation( "target.xdata = a.xdata[:,:,0:8]", map) document_model.recompute_all() assert numpy.array_equal(data_item2.data, d[:, :, 0:8]) display_item = document_model.get_display_item_for_data_item( data_item2) display_data_channel = display_item.display_data_channels[0] display_data_channel.slice_center = 6 display_data_channel.slice_width = 4 self.assertEqual(display_data_channel.slice_center, 6) self.assertEqual(display_data_channel.slice_width, 4) document_model.get_data_item_computation( display_item.data_item ).expression = "target.xdata = a.xdata[:, :, 0:4]" document_model.recompute_all() self.assertEqual(display_data_channel.slice_center, 3) self.assertEqual(display_data_channel.slice_width, 2)
def test_computation_inspector_panel_handles_computation_being_removed_implicitly( self): with TestContext.create_memory_context() as test_context: document_controller = test_context.create_document_controller() document_model = document_controller.document_model data_item = DataItem.DataItem(numpy.zeros((10, ))) document_model.append_data_item(data_item) display_item = document_model.get_display_item_for_data_item( data_item) interval = Graphics.IntervalGraphic() display_item.add_graphic(interval) interval2 = Graphics.IntervalGraphic() display_item.add_graphic(interval2) data_item2 = DataItem.DataItem(numpy.zeros((10, ))) document_model.append_data_item(data_item2) display_item2 = document_model.get_display_item_for_data_item( data_item2) data_item3 = DataItem.DataItem(numpy.zeros((10, ))) document_model.append_data_item(data_item3) display_item3 = document_model.get_display_item_for_data_item( data_item3) computation = document_model.create_computation() computation.create_input_item("src", Symbolic.make_item(data_item)) computation.create_input_item("interval", Symbolic.make_item(interval)) computation.create_input_item("interval2", Symbolic.make_item(interval2)) computation.create_output_item("dst", Symbolic.make_item(data_item2)) computation.create_output_item("dst2", Symbolic.make_item(data_item3)) document_model.append_computation(computation) interval2.source = interval display_item.append_display_data_channel_for_data_item(data_item2) display_item.append_display_data_channel_for_data_item(data_item3) with contextlib.closing( ComputationPanel.InspectComputationDialog( document_controller, computation)): display_item.remove_graphic(interval)
def select_button_clicked(): for variable in self.computation._computation.variables: if variable.name == "align_region": self.computation._computation.remove_variable(variable) graphics = document_controller.target_display.selected_graphics or list() align_region = None for graphic in graphics: if graphic.graphic_type == "rect-graphic": align_region = graphic break if align_region: self.computation._computation.create_input_item("align_region", Symbolic.make_item(align_region._graphic))
def select_button_clicked(): graphics = document_controller.target_display.selected_graphics if not graphics: return try: while True: self.computation._computation.remove_item_from_objects( 'map_regions', 0) except IndexError: pass for graphic in graphics: self.computation._computation.insert_item_into_objects( 'map_regions', 0, Symbolic.make_item(graphic._graphic))
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_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_change_variable_command_resulting_in_creating_data_item_undo_redo( self): with TestContext.create_memory_context() as test_context: document_controller = test_context.create_document_controller() document_model = document_controller.document_model # setup data_item1 = DataItem.DataItem(numpy.zeros((10, 10))) document_model.append_data_item(data_item1) data_item2 = DataItem.DataItem(numpy.zeros((10, 10))) document_model.append_data_item(data_item2) data_item3 = DataItem.DataItem(numpy.zeros((10, ))) document_model.append_data_item(data_item3) computation = document_model.create_computation( "target.xdata = a.xdata[1] + x") variable = computation.create_input_item( "a", Symbolic.make_item(data_item3)) computation.create_variable("x", value_type="integral", value=5) document_model.set_data_item_computation(data_item1, computation) # verify setup self.assertEqual(data_item3, computation.get_input("a")) document_model.recompute_all() document_controller.periodic() self.assertIsNotNone(computation.error_text) # change variable properties = { "variable_type": "data_item", "specified_object": data_item2 } command = Inspector.ChangeComputationVariableCommand( document_controller.document_model, computation, variable, **properties) command.perform() document_controller.push_undo_command(command) # verify change and trigger computation self.assertEqual(data_item2, computation.get_input("a")) document_model.recompute_all() document_controller.periodic() self.assertIsNone(computation.error_text) # undo and verify document_controller.handle_undo() self.assertEqual(data_item3, computation.get_input("a")) document_model.recompute_all() document_controller.periodic() self.assertIsNotNone(computation.error_text) # redo and verify document_controller.handle_redo() document_model.recompute_all() document_controller.periodic() self.assertEqual(data_item2, computation.get_input("a")) self.assertIsNone(computation.error_text)
def test_connection_establishes_transaction_on_target_data_structure_dependent( self): with TestContext.create_memory_context() as test_context: document_model = test_context.create_document_model() data_item = DataItem.DataItem(numpy.zeros((20, ))) document_model.append_data_item(data_item) display_item = document_model.get_display_item_for_data_item( data_item) interval = Graphics.IntervalGraphic() display_item.add_graphic(interval) data_struct = document_model.create_data_structure() data_struct.set_property_value("x_interval", (0.5, 0.1)) document_model.append_data_structure(data_struct) connection = Connection.PropertyConnection(data_struct, "x_interval", interval, "interval", parent=data_item) document_model.append_connection(connection) computed_data_item = DataItem.DataItem(numpy.zeros((100, ))) document_model.append_data_item(computed_data_item) computation = document_model.create_computation( Symbolic.xdata_expression("a.xdata")) computation.create_input_item("a", Symbolic.make_item(data_item)) computation.create_input_item("d", Symbolic.make_item(data_struct)) document_model.set_data_item_computation(computed_data_item, computation) with document_model.item_transaction(data_item): self.assertTrue( document_model.is_in_transaction_state(data_item)) self.assertTrue( document_model.is_in_transaction_state(display_item)) self.assertTrue( document_model.is_in_transaction_state(data_struct)) self.assertTrue( document_model.is_in_transaction_state(computed_data_item)) self.assertEqual(0, document_model.transaction_count)
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 menu_item_execute(self, window: API.DocumentWindow) -> None: document_controller = window._document_controller selected_display_item = document_controller.selected_display_item data_item = (selected_display_item.data_items[0] if selected_display_item and len(selected_display_item.data_items) > 0 else None) if data_item: api_data_item = Facade.DataItem(data_item) if not api_data_item.xdata.is_data_4d: self.__show_tool_tips('wrong_shape') return map_data_item = self.__api.library.create_data_item( title='Map 4D of ' + data_item.title) # the following uses internal API and should not be used as example code. computation = document_controller.document_model.create_computation( ) computation.create_input_item( "src", Symbolic.make_item( selected_display_item. get_display_data_channel_for_data_item(data_item))) computation.create_input_item("map_regions", Symbolic.make_item_list([])) computation.processing_id = "nion.map_4d.2" document_controller.document_model.set_data_item_computation( map_data_item._data_item, computation) map_display_item = document_controller.document_model.get_display_item_for_data_item( map_data_item._data_item) document_controller.show_display_item(map_display_item) graphic = Graphics.PointGraphic() graphic.label = "Pick" graphic.role = "collection_index" map_display_item.add_graphic(graphic) # see note above. self.__computation_data_items.update({ str(data_item.uuid): 'source', str(map_data_item._data_item.uuid): 'map_4d' }) self.__show_tool_tips() self.__display_item_changed_event_listener = ( document_controller.focused_display_item_changed_event.listen( self.__display_item_changed))
def test_expression_updates_when_node_is_changed(self): document_model = DocumentModel.DocumentModel() document_controller = DocumentController.DocumentController(self.app.ui, document_model, workspace_id="library") with contextlib.closing(document_controller): data_item1 = DataItem.DataItem(numpy.zeros((10, 10))) document_model.append_data_item(data_item1) data_item2 = DataItem.DataItem(numpy.zeros((10, 10))) document_model.append_data_item(data_item2) computation = document_model.create_computation("target.xdata = -a.xdata") computation.create_input_item("a", Symbolic.make_item(data_item1)) document_model.set_data_item_computation(data_item2, computation) panel = ComputationPanel.EditComputationDialog(document_controller, data_item2) document_controller.periodic() # execute queue text1 = panel._text_edit_for_testing.text document_model.get_data_item_computation(data_item2).expression = "target.xdata = -a.xdata + 1" document_controller.periodic() # execute queue text2 = panel._text_edit_for_testing.text self.assertNotEqual(text2, text1)
def test_change_variable_command_resulting_in_creating_data_item_undo_redo(self): document_model = DocumentModel.DocumentModel() document_controller = DocumentController.DocumentController(self.app.ui, document_model, workspace_id="library") with contextlib.closing(document_controller): # setup data_item1 = DataItem.DataItem(numpy.zeros((10, 10))) document_model.append_data_item(data_item1) data_item2 = DataItem.DataItem(numpy.zeros((10, 10))) document_model.append_data_item(data_item2) data_item3 = DataItem.DataItem(numpy.zeros((10, ))) document_model.append_data_item(data_item3) computation = document_model.create_computation("target.xdata = a.xdata[1] + x") variable = computation.create_input_item("a", Symbolic.make_item(data_item3)) computation.create_variable("x", value_type="integral", value=5) document_model.set_data_item_computation(data_item1, computation) # verify setup self.assertEqual(data_item3, computation.get_input("a")) document_model.recompute_all() document_controller.periodic() self.assertIsNotNone(computation.error_text) # change variable variable_specifier = document_model.get_object_specifier(data_item2) properties = {"variable_type": "data_item", "specifier": variable_specifier} command = ComputationPanel.ComputationModel.ChangeVariableCommand(document_controller.document_model, computation, variable, **properties) command.perform() document_controller.push_undo_command(command) # verify change and trigger computation self.assertEqual(data_item2, computation.get_input("a")) document_model.recompute_all() document_controller.periodic() self.assertIsNone(computation.error_text) # undo and verify document_controller.handle_undo() self.assertEqual(data_item3, computation.get_input("a")) document_model.recompute_all() document_controller.periodic() self.assertIsNotNone(computation.error_text) # redo and verify document_controller.handle_redo() document_model.recompute_all() document_controller.periodic() self.assertEqual(data_item2, computation.get_input("a")) self.assertIsNone(computation.error_text)
def select_button_clicked(channel): graphics = document_controller.target_display.selected_graphics if not graphics: return try: while True: self.computation._computation.remove_item_from_objects( f'map_regions_{channel}', 0) except IndexError: pass for graphic in graphics: self.computation._computation.insert_item_into_objects( f'map_regions_{channel}', 0, Symbolic.make_item(graphic._graphic)) title_suffix = f' ({channel.upper()})' title = graphic.label or '' if not title.endswith(title_suffix): title += title_suffix graphic.label = title
def test_clearing_computation_clears_text_and_unbinds_or_whatever(self): document_model = DocumentModel.DocumentModel() document_controller = DocumentController.DocumentController(self.app.ui, document_model, workspace_id="library") with contextlib.closing(document_controller): data_item1 = DataItem.DataItem(numpy.zeros((10, 10))) document_model.append_data_item(data_item1) data_item2 = DataItem.DataItem(numpy.zeros((10, 10))) document_model.append_data_item(data_item2) computation = document_model.create_computation("target.xdata = -a.xdata") computation.create_input_item("a", Symbolic.make_item(data_item1)) document_model.set_data_item_computation(data_item2, computation) panel = ComputationPanel.EditComputationDialog(document_controller, data_item2) document_controller.periodic() # execute queue panel._text_edit_for_testing.text = "" panel._update_button.on_clicked() document_controller.periodic() self.assertIsNone(document_model.get_data_item_computation(data_item2)) text2 = panel._text_edit_for_testing.text self.assertFalse(text2)
def select_button_clicked(): graphics = Facade.DataItem( self.computation._computation.source).graphics if not graphics: return graphics_variable = self.computation._computation._get_variable( 'map_regions') graphics_variable.disconnect_items() if graphics_variable.bound_items_model is None: return num_items = len(graphics_variable.bound_items_model.items) for _ in range(num_items): self.computation._computation.remove_item_from_objects( 'map_regions', 0) for graphic in graphics: if graphic._graphic.role == 'mask': self.computation._computation.insert_item_into_objects( 'map_regions', 0, Symbolic.make_item(graphic._graphic, type='graphic'))
def test_expression_updates_when_node_is_changed(self): with TestContext.create_memory_context() as test_context: document_controller = test_context.create_document_controller() document_model = document_controller.document_model data_item1 = DataItem.DataItem(numpy.zeros((10, 10))) document_model.append_data_item(data_item1) data_item2 = DataItem.DataItem(numpy.zeros((10, 10))) document_model.append_data_item(data_item2) computation = document_model.create_computation( "target.xdata = -a.xdata") computation.create_input_item("a", Symbolic.make_item(data_item1)) document_model.set_data_item_computation(data_item2, computation) panel = ComputationPanel.EditComputationDialog( document_controller, data_item2) document_controller.periodic() # execute queue text1 = panel._text_edit_for_testing.text document_model.get_data_item_computation( data_item2).expression = "target.xdata = -a.xdata + 1" document_controller.periodic() # execute queue text2 = panel._text_edit_for_testing.text self.assertNotEqual(text2, text1)
def test_clearing_computation_clears_text_and_unbinds_or_whatever(self): with TestContext.create_memory_context() as test_context: document_controller = test_context.create_document_controller() document_model = document_controller.document_model data_item1 = DataItem.DataItem(numpy.zeros((10, 10))) document_model.append_data_item(data_item1) data_item2 = DataItem.DataItem(numpy.zeros((10, 10))) document_model.append_data_item(data_item2) computation = document_model.create_computation( "target.xdata = -a.xdata") computation.create_input_item("a", Symbolic.make_item(data_item1)) document_model.set_data_item_computation(data_item2, computation) panel = ComputationPanel.EditComputationDialog( document_controller, data_item2) document_controller.periodic() # execute queue panel._text_edit_for_testing.text = "" # no longer clears the computation. cm 2020-08. panel._update_button.on_clicked() document_controller.periodic() self.assertIsNotNone( document_model.get_data_item_computation(data_item2)) text2 = panel._text_edit_for_testing.text self.assertFalse(text2)
def test_error_text_cleared_after_invalid_script_becomes_valid(self): # similar to test_invalid_expression_shows_error_and_clears_it except periodic occurs before recompute at end with TestContext.create_memory_context() as test_context: document_controller = test_context.create_document_controller() document_model = document_controller.document_model data_item1 = DataItem.DataItem(numpy.zeros((10, 10))) document_model.append_data_item(data_item1) data_item2 = DataItem.DataItem(numpy.zeros((10, 10))) document_model.append_data_item(data_item2) computation = document_model.create_computation( "target.xdata = -a.xdata") computation.create_input_item("a", Symbolic.make_item(data_item1)) document_model.set_data_item_computation(data_item2, computation) panel = ComputationPanel.EditComputationDialog( document_controller, data_item2) document_controller.periodic( ) # let the inspector see the computation document_controller.periodic() # and update the computation expression = panel._text_edit_for_testing.text self.assertFalse(panel._error_label_for_testing.text.strip()) panel._text_edit_for_testing.text = "target.xdata = xyz(a.xdata)" panel._update_button.on_clicked() # the sequence of periodic/recompute_all is intentional, to test various computation states document_controller.periodic() document_model.recompute_all() document_model.recompute_all() document_controller.periodic() self.assertEqual(panel._text_edit_for_testing.text, "target.xdata = xyz(a.xdata)") self.assertTrue(len(panel._error_label_for_testing.text) > 0) panel._text_edit_for_testing.text = expression panel._update_button.on_clicked() # the sequence of periodic/recompute_all is intentional, to test various computation states document_controller.periodic() document_model.recompute_all() document_model.recompute_all() document_controller.periodic() self.assertEqual(panel._text_edit_for_testing.text, expression) self.assertIsNone(panel._error_label_for_testing.text)
async def change_edge( document_controller: DocumentController.DocumentController, model_data_item: DataItem.DataItem, eels_data_item: DataItem.DataItem, edge: "ElementalMappingEdge") -> None: """Change the eels data item and associated items to display new edge. The library will be changed in the following way: - the pick region will be renamed - the pick data item will connect fit/signal regions to new edge data structure - the background subtraction computation will use edge intervals from new edge - the pick, background, subtracted, and eels line plot data items will be renamed - the eels line plot will connect fit/signal regions to new edge data structure - the edge reference will reference the new edge """ document_model = document_controller.document_model project = document_model._project computation = None # type: Symbolic.Computation for computation_ in document_model.computations: if computation_.source == eels_data_item and computation_.processing_id == "eels.background_subtraction11": computation = computation_ break edge_ref_data_structure = None old_edge_data_structure = None for data_structure in document_model.data_structures: if data_structure.source == eels_data_item and data_structure.structure_type == "elemental_mapping_edge_ref": edge_ref_data_structure = data_structure old_edge_data_structure = data_structure.get_referenced_object( "edge") break if not computation or not edge_ref_data_structure or not old_edge_data_structure: return pick_region = edge_ref_data_structure.get_referenced_object("pick_region") if not eels_data_item or not pick_region: return pick_region.label = "{} {}".format(_("Pick"), str(edge.electron_shell)) for connection in copy.copy(document_model.connections): if connection.parent == eels_data_item and connection.source_property in ( "fit_interval", "signal_interval"): source_property = connection.source_property target_property = connection.target_property target = connection._target document_model.remove_connection(connection) new_connection = Connection.PropertyConnection( edge.data_structure, source_property, target, target_property, parent=eels_data_item) document_model.append_connection(new_connection) computation.set_input_item("fit_interval", Symbolic.make_item(edge.data_structure)) computation.set_input_item("signal_interval", Symbolic.make_item(edge.data_structure)) eels_data_item.title = "{} EELS Data of {}".format(pick_region.label, model_data_item.title) for connection in copy.copy(document_model.connections): if connection.parent == eels_data_item and connection.source_property in ( "fit_interval", "signal_interval"): source_property = connection.source_property target_property = connection.target_property target = connection._target document_model.remove_connection(connection) new_connection = Connection.PropertyConnection( edge.data_structure, source_property, target, target_property, parent=eels_data_item) document_model.append_connection(new_connection) edge_ref_data_structure.remove_referenced_object("edge") edge_ref_data_structure.set_referenced_object("edge", edge.data_structure) # the eels item will need the initial computation results to display properly (view to intervals) await document_model.compute_immediate(document_controller.event_loop, computation) eels_display_item = document_model.get_display_item_for_data_item( eels_data_item) eels_display_item.view_to_intervals( eels_data_item.xdata, [edge.fit_interval, edge.signal_interval])
async def pick_new_edge(document_controller, model_data_item, edge) -> None: """Set up a new edge pick from the model data item and the given edge. The library will have the following new components and connections: - a pick region on the model data item - a pick data item with a fit/signal connected to the edge data structure - a background subtraction computation with model data item, and edge intervals as inputs - a background data item, computed by the background subtraction computation - a subtracted data item, computed by the background subtraction computation - a eels line plot with pick, background, and subtracted data items as components - an edge reference, owned by eels line plot, with reference to edge - the edge reference is used to recognize the eels line plot as associated with the referenced edge """ document_model = document_controller.document_model project = document_model._project model_display_item = document_model.get_display_item_for_data_item( model_data_item) pick_region = Graphics.RectangleGraphic() pick_region.size = min(1 / 16, 16 / model_data_item.dimensional_shape[0]), min( 1 / 16, 16 / model_data_item.dimensional_shape[1]) pick_region.label = "{} {}".format(_("Pick"), str(edge.electron_shell)) model_display_item.add_graphic(pick_region) # set up the computation for this edge. eels_data_item = DataItem.DataItem() document_model.append_data_item(eels_data_item) eels_data_item.title = "{} EELS Data of {}".format(pick_region.label, model_data_item.title) eels_data_item.source = pick_region eels_display_item = document_model.get_display_item_for_data_item( eels_data_item) eels_display_item.display_type = "line_plot" eels_display_item._set_display_layer_properties(0, label=_("Signal"), data_row=2, fill_color="#0F0") eels_display_item._add_display_layer_for_data_item( eels_data_item, label=_("Background"), data_row=1, fill_color="rgba(255, 0, 0, 0.3)") eels_display_item._add_display_layer_for_data_item(eels_data_item, label=_("Data"), data_row=0, fill_color="#1E90FF") eels_display_item.set_display_property("legend_position", "top-right") fit_region = Graphics.IntervalGraphic() fit_region.label = _("Fit") fit_region.graphic_id = "fit" fit_region.interval = edge.fit_interval eels_display_item.add_graphic(fit_region) signal_region = Graphics.IntervalGraphic() signal_region.label = _("Signal") signal_region.graphic_id = "signal" signal_region.interval = edge.signal_interval eels_display_item.add_graphic(signal_region) document_model.append_connection( Connection.PropertyConnection(edge.data_structure, "fit_interval", fit_region, "interval", parent=eels_data_item)) document_model.append_connection( Connection.PropertyConnection(edge.data_structure, "signal_interval", signal_region, "interval", parent=eels_data_item)) computation = document_model.create_computation() computation.create_input_item( "eels_xdata", Symbolic.make_item(model_data_item, type="xdata")) computation.create_input_item("region", Symbolic.make_item(pick_region)) computation.create_input_item("fit_interval", Symbolic.make_item(edge.data_structure), property_name="fit_interval") computation.create_input_item("signal_interval", Symbolic.make_item(edge.data_structure), property_name="signal_interval") computation.processing_id = "eels.background_subtraction11" computation.create_output_item("data", Symbolic.make_item(eels_data_item)) document_model.append_computation(computation) # the eels item will need the initial computation results to display properly (view to intervals) await document_model.compute_immediate(document_controller.event_loop, computation) # ensure computation is deleted when eels is deleted computation.source = eels_data_item # create an elemental_mapping_edge_ref data structure, owned by the eels data item, with a referenced # object pointing to the edge. used for recognizing the eels data item as such. data_structure = document_model.create_data_structure( structure_type="elemental_mapping_edge_ref", source=eels_data_item) data_structure.set_referenced_object("spectrum_image", model_data_item) data_structure.set_referenced_object("edge", edge.data_structure) data_structure.set_referenced_object("data", eels_data_item) data_structure.set_referenced_object("pick_region", pick_region) document_model.append_data_structure(data_structure) # display it eels_display_item.view_to_intervals(eels_data_item.xdata, [ edge.data_structure.fit_interval, edge.data_structure.signal_interval ]) document_controller.show_display_item(eels_display_item)