def selectRows(self, searchStr: str): if self.selectedColumn == -1: Task.showMessage( "Workflow violation", "", "Must select a table column before this operation can be applied", QMessageBox.Warning) else: print(f"SELECT: {searchStr}") rows = self.table.rowCount() srows = ItemContainer() self._selected_rows = [] for iRow in range(rows): item: QTableWidgetItem = self.table.item( iRow, self.selectedColumn) try: match: re.Match = re.match(searchStr, item.text()) if (match is not None): pid_item: QTableWidgetItem = self.table.item( iRow, self._index_column) try: srows.add(self.getRS(iRow, int(pid_item.text()), 0)) self._selected_rows.append(iRow) except: pass except: break self.selectRowsByIndex(srows, False) if (self.name == "catalog"): event = dict(event="pick", type="directory", rows=srows, mark=False, source=self.name) self.submitEvent(event, EventMode.Gui)
def build_model(self, *args, **kwargs): if self.block is None: Task.taskNotAvailable( "Workflow violation", "Must load a block first", **kwargs ) else: labels: xa.DataArray = self.getExtendedLabelPoints() umapManager.embed( self.block, labels, **kwargs ) self.plot_markers_volume()
def apply(self, block: Block, **kwargs ) -> Optional[xa.DataArray]: if (self.learned_mapping is None) or (self.learned_mapping.embedding is None): Task.taskNotAvailable( "Workflow violation", "Must learn a classication before it can be applied", **kwargs ) return None point_data: xa.DataArray = block.getPointData( **kwargs ) embedding: np.ndarray = self.learned_mapping.transform( point_data ) return self.wrap_embedding( point_data.coords['samples'], embedding )
def findRow(self, searchStr: str): if self.selectedColumn == -1: Task.showMessage( "Workflow violation", "", "Must select a table column before this operation can be applied", QMessageBox.Warning) else: if not searchStr.startswith(self._current_search_str): self._search_row = 0 print(f"FIND: {searchStr}") rows = self.table.rowCount() for iRow in range(self._search_row, rows): item: QTableWidgetItem = self.table.item( iRow, self.selectedColumn) try: if item.text().startswith(searchStr): pid_item: QTableWidgetItem = self.table.item( iRow, self._index_column) try: pid = int(pid_item.text()) srows = ItemContainer([self.getRS(iRow, pid, 0)]) self.selectRowsByIndex(srows, False) self._current_search_str = searchStr self._search_row = iRow event = dict(event="pick", type="directory", rows=srows, mark=False, source=self.name) self.submitEvent(event, EventMode.Gui) except: pass break except: break
def learn_classification( self, **kwargs ): if self.block is None: Task.taskNotAvailable( "Workflow violation", "Must load a block and spread some labels first", **kwargs ) else: full_labels: xa.DataArray = self.getExtendedLabelPoints() print( f"Learning Classification, labels shape = {full_labels.shape}, nLabels = {np.count_nonzero( full_labels > 0 )}") event = dict(event="classify", type="learn", data=self.block, labels=full_labels ) self.submitEvent( event, EventMode.Gui )
def onMouseClick(self, event): try: if event.xdata != None and event.ydata != None: if not self.toolbarMode and (event.inaxes == self.plot_axes) and (self.key_mode == None): rightButton: bool = int(event.button) == self.RIGHT_BUTTON pid = self.block.coords2pindex( event.ydata, event.xdata ) if pid >= 0: ptindices = self.block.pindex2indices(pid) classification = self.label_map.values[ ptindices['iy'], ptindices['ix'] ] if (self.label_map is not None) else -1 cid = labelsManager.selectedClass marker = Marker( labelsManager.colors[cid], [pid], labelsManager.selectedClass ) self.add_marker( marker, labelsManager.selectedClass == 0, classification=classification ) self.dataLims = event.inaxes.dataLim except Exception as err: Task.showErrorMessage( f"LabelingConsole pick error: {err}" ) traceback.print_exc(50)
def processEvent(self, event: Dict): from hyperclass.gui.tasks import taskRunner, Task from hyperclass.data.events import dataEventHandler from hyperclass.graph.flow import activationFlowManager super().processEvent(event) if dataEventHandler.isDataLoadEvent(event): point_data = dataEventHandler.getPointData(event, DataType.Embedding) if point_data.size == 0: Task.showMessage("Data access warning", "", "This block does not have any valid data", QMessageBox.Warning) else: self.initLabelsData(point_data) self._flow = activationFlowManager.getActivationFlow( point_data)
def loadCurrentBlock(self, **kwargs): filename = dataManager.config.value("data/init/file", None) if filename is not None: buttonReply = QMessageBox.question( self, 'Hyperclass Initialization', "Load current block?", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) if buttonReply == QMessageBox.Yes: taskRunner.start( Task(f"load dataset", self.openFile, filename, **kwargs))
def setTile(self, tile_coords: Tuple[int], **kwargs): current_tile_coords = dataManager.config.value("tile/indices", None) if current_tile_coords is None or current_tile_coords != tile_coords: print(f"Setting tile indices = {tile_coords}") dataManager.config.setValue("tile/indices", tile_coords) filename = dataManager.config.value("data/init/file", None) if filename is not None: taskRunner.start( Task(f"Load New Tile", self.openFile, filename, **kwargs)) self.update_tile_load_menu.emit()
def selectFile(self, *args, **kwargs): data_dir = dataManager.config.value('data/dir') dialog = QFileDialog(self, "Select File", data_dir) dialog.setFileMode(QFileDialog.AnyFile) dialog.setViewMode(QFileDialog.Detail) if (dialog.exec()): fileNames = dialog.selectedFiles() taskRunner.start( Task(f"load dataset", self.openFile, fileNames[0], **kwargs)) dialog.close()
def runLoadDataset(self, dsid: str, **kwargs): load_dataset_in_background = True if load_dataset_in_background: taskRunner.start( Task(f"Load Dataset {dsid}", self.loadDataset, dsid, **kwargs)) else: dset = self.loadDataset(dsid, **kwargs) event = dict(event='task', type='result', label='load dataset', result=dset) self.submitEvent(event, EventMode.Gui)
def processEvent(self, event: Dict): if event.get('event') == 'gui': if event.get('type') == 'update': self.refresh_points(**event) self.refresh_images(**event) print("GUI UPDATE") self.update() self.repaint() if event.get('type') == 'reload': filename = dataManager.config.value("data/init/file", None) if filename is not None: taskRunner.start( Task(f"load dataset", self.openFile, filename, reset=True))
def __init__(self, nodes_data: xa.DataArray, **kwargs): QObject.__init__(self) self.nodes: xa.DataArray = None self.nnd: NNDescent = None self.I: np.ndarray = None self.D: np.ndarray = None self.P: np.ndarray = None self.C: np.ndarray = None self.reset = True background = kwargs.get('background', False) if background: self.init_task = Task(f"Compute NN graph", self.setNodeData, nodes_data, **kwargs) taskRunner.start(self.init_task) else: self.setNodeData(nodes_data, **kwargs)
def submitEvent(self, event: Dict, mode: EventMode): from hyperclass.data.events import dataEventHandler from hyperclass.gui.tasks import taskRunner, Task try: dataEventHandler.reset(event) except: pass if mode == EventMode.Gui: self.process_event.emit(event) else: for client in self._clients: if mode == EventMode.Foreground: client.processEvent(event) elif mode == EventMode.Background: print( f"\n**** CLASS {self.__class__.__name__}: submit background event {event}" ) task_label = ".".join([ event.get(id, "") for id in ['event', 'type', 'label'] ]) task = Task(task_label, client.processEvent, event) taskRunner.start(task)
def spread(self, sample_labels: xa.DataArray, nIter: int = 1, **kwargs) -> Optional[xa.Dataset]: if self.D is None: Task.showMessage("Awaiting task completion", "", "The NN graph computation has not yet finished", QMessageBox.Critical) return None sample_data = sample_labels.values sample_mask = sample_data == 0 if self.C is None or self.reset: self.C = sample_data else: self.C = np.where(sample_mask, self.C, sample_data) label_count = np.count_nonzero(self.C) if label_count == 0: Task.showMessage( "Workflow violation", "", "Must label some points before this algorithm can be applied", QMessageBox.Critical) return None if (self.P is None) or self.reset: self.P = np.full(self.C.shape, float('inf'), dtype=np.float32) self.P = np.where(sample_mask, self.P, 0.0) print(f"Beginning graph flow iterations, #C = {label_count}") t0 = time.time() converged = False for iter in range(nIter): try: iterate_spread_labels(self.I, self.D, self.C, self.P) new_label_count = np.count_nonzero(self.C) if new_label_count == label_count: print("Converged!") converged = True break else: label_count = new_label_count # print(f"\n -->> Iter{iter + 1}: #C = {label_count}\n") except Exception as err: print(f"Error in graph flow iteration {iter}:") traceback.print_exc(50) break t1 = time.time() result_attrs = dict(converged=converged, **sample_labels.attrs) result_attrs['_FillValue'] = -2 xC: xa.DataArray = xa.DataArray(self.C, dims=sample_labels.dims, coords=sample_labels.coords, attrs=result_attrs) xP: xa.DataArray = xa.DataArray(self.P, dims=sample_labels.dims, coords=sample_labels.coords, attrs=result_attrs) print( f"Completed graph flow {nIter} iterations in {(t1 - t0)} sec, Class Range = [ {xC.min().values} -> {xC.max().values} ], #marked = {np.count_nonzero(xC.values)}" ) self.reset = False return xa.Dataset(dict(C=xC, D=xP))
def runSetBlock(self, coords, **kwargs): taskRunner.start(Task("Loading block", self.setBlock, coords, **kwargs))
def runSetTile(self, coords, **kwargs): taskRunner.start(Task("Loading tile", self.setTile, coords, **kwargs))
def run_task(self, executable: Callable, messsage: str, *args, **kwargs ): task = Task( messsage, executable, *args, **kwargs ) taskRunner.start( task )