def updateTree(self): """ Rebuilds the tree from the current state of the DataStore. """ self.tree.DeleteAllItems() self.root = self.tree.AddRoot("Project") self.tree.SetPyData(self.root, None) self.tree.SetItemImage(self.root, self.fldridx, wx.TreeItemIcon_Normal) self.tree.SetItemImage(self.root, self.fldropenidx, wx.TreeItemIcon_Expanded) dataTree = self.tree.AppendItem(self.root, "Data Sets") self.tree.SetPyData(dataTree, DATA_SET_ITEM) self.tree.SetItemImage(dataTree, self.fldridx, wx.TreeItemIcon_Normal) self.tree.SetItemImage(dataTree, self.fldropenidx, wx.TreeItemIcon_Expanded) figsTree = self.tree.AppendItem(self.root, "Figure Sets") self.tree.SetPyData(figsTree, FIGURE_SET_ITEM) self.tree.SetItemImage(figsTree, self.fldridx, wx.TreeItemIcon_Normal) self.tree.SetItemImage(figsTree, self.fldropenidx, wx.TreeItemIcon_Expanded) # create tree self.buildDataTree(dataTree, DataStore.getData(), []) self.buildFigureTree(figsTree, FigureStore.getFigures()) self.tree.Expand(self.root) if self.dataTreeExpanded: self.tree.Expand(dataTree) if self.figureTreeExpanded: self.tree.Expand(figsTree)
def __init__(self, parent): wx.Dialog.__init__(self, parent, wx.ID_ANY, "Select clusterings to match colors", style=wx.RESIZE_BORDER|wx.DEFAULT_DIALOG_STYLE, size=(400, 150)) self.CenterOnParent() allData = DataStore.getData() self.choices = [] self.choiceIDs = [] # Populate the choices list with string, and populate the # choiceIDs list with (dataID, clusteringID) tuples so the # combo box selection can be tied to the data for didx in allData: fcData = allData[didx] for cidx in fcData.clustering: self.choices.append(fcData.displayname + ": " + getStringRepr(fcData.methodIDs[cidx]) + " " + str(cidx+1)) self.choiceIDs.append((fcData.ID, cidx)) self.cbxSourceClustering = wx.ComboBox(self, choices=self.choices, style=wx.CB_READONLY) self.cbxDestClustering = wx.ComboBox(self, choices=self.choices, style=wx.CB_READONLY) self.formSizer = wx.FlexGridSizer(2, 2, vgap=5, hgap=5) self.formSizer.FlexibleDirection = wx.HORIZONTAL self.formSizer.AddF(wx.StaticText(self, -1, 'First Clustering:'), wx.SizerFlags(1).Expand()) self.formSizer.AddF(self.cbxSourceClustering, wx.SizerFlags(2).Expand()) self.formSizer.AddF(wx.StaticText(self, -1, 'Second Clustering:'), wx.SizerFlags(1).Expand()) self.formSizer.AddF(self.cbxDestClustering, wx.SizerFlags(2).Expand()) self.Sizer = wx.BoxSizer(wx.VERTICAL) self.Sizer.AddF(self.formSizer, wx.SizerFlags(1).Expand().Border(wx.ALL, 10)) self.Sizer.AddF(self.CreateButtonSizer(wx.OK|wx.CANCEL), wx.SizerFlags().Expand().Border(wx.BOTTOM, 10))
def deleteSelection(self): """ Delete the data object referenced by the current tree selection. """ item = self.getSanitizedItemSelectionData() if item is None: return if item[0] is DATA_SET_ITEM: ids = (item[1], None) if len(item) < 3 else (item[1], item[2]) self.Parent.TopLevelParent.facsPlotPanel.deleteAssociatedSubplots(ids) self.applyToSelection(DataStore.remove, FacsData.removeClustering) # if all data deleted, clear axes selectors if len(DataStore.getData()) == 0: self.Parent.TopLevelParent.updateAxesList([]) if item[0] is FIGURE_SET_ITEM: id = item[1] #TODO: figure out if this is a good shortcut for clearing the figure of subplots if id == FigureStore.getSelectedIndex(): wx.MessageBox('The currently selected Figure cannot be deleted.', 'Invalid Action', wx.OK | wx.ICON_WARNING) else: FigureStore.remove(id) self.updateTree()
def setExpanded(self, item, flag): #item = self.getItemSelectionData() data = self.tree.GetItemPyData(item) if isinstance(data, int): if data is DATA_SET_ITEM: self.dataTreeExpanded = flag if data is FIGURE_SET_ITEM: self.figureTreeExpanded = flag if isinstance(data, tuple): if data[0] is DATA_SET_ITEM: if len(data) == 2: DataStore.getData()[data[1]].nodeExpanded = flag if len(data) > 3: DataStore.getData()[data[1]].infoExpanded[data[2]] = flag
def reassignClusterIDs(src, dst): """ Given the cluster centers for two clusterings, determine the centers most similar to each other and reassign the cluster ids to match. """ srcFCS = DataStore.getData()[src[0]] dstFCS = DataStore.getData()[dst[0]] srcdata = srcFCS.data if srcFCS.selDims: srcdata = dh.filterData(srcFCS.data, srcFCS.selDims) srcids = srcFCS.clustering[src[1]] srccenters = pc.clustercentroids(srcdata, clusterid=srcids)[0] dstdata = dstFCS.data if dstFCS.selDims: dstdata = dh.filterData(dstFCS.data, dstFCS.selDims) dstids = dstFCS.clustering[dst[1]] dstcenters = pc.clustercentroids(dstdata, clusterid=dstids)[0] srcsep = separate(srcdata, srcids) dstsep = separate(dstdata, dstids) centerEQ = {} taken = [] # Fill the map with the closest source center for each destination center for i,dc in enumerate(dstcenters): bestDist = -1 for j,sc in enumerate(srccenters): if (j not in taken): dist = nonSymmetricClusterDistance(dstsep[i], srcsep[j]) if (bestDist < 0) or (dist < bestDist): bestDist = dist centerEQ[i] = j taken.append(centerEQ[i]) # Renumber the cluster IDs in the destination to match the IDs of the closest src center tmp = [centerEQ[id] for id in dstids] DataStore.getData()[dst[0]].clustering[dst[1]] = tmp
def OnAddFigure(self, event): if len(DataStore.getData()) == 0: return nameDlg = displayDialogs.EditNameDialog(self, '') if (nameDlg.ShowModal() == wx.ID_OK): newFig = Figure(nameDlg.Text, [dv.Subplot()], 1, (1,1), (0,1)) currFig = FigureStore.getSelectedFigure() FigureStore.add(newFig) dv.switchFigures(self.facsPlotPanel, currFig, newFig) self.facsPlotPanel.subplots = [] self.addSubplot() self.treeCtrlPanel.updateTree() nameDlg.Destroy()
def OnLoadState(self, event): from data.io import loadState if len(DataStore.getData()) > 0: dlgWarn = wx.MessageDialog(self, 'This action may overwrite currently loaded datasets and/or plots.\n\nContinue anyway?', 'Warning', wx.YES_NO | wx.NO_DEFAULT | wx.ICON_WARNING) if dlgWarn.ShowModal() == wx.ID_NO: dlgWarn.Destroy() return dlgWarn.Destroy() formats = "FIND Project File (*.find)|*.find" dlg = wx.FileDialog(self, "Select saved project", self.dirname, "", formats, wx.FD_OPEN) if dlg.ShowModal() == wx.ID_OK: try: loadState(dlg.Directory, dlg.Filename) except error.ProjectLoadingError: return # Load all Figures with Subplot instances from the stored dicts for fID in FigureStore.getFigures(): fig = FigureStore.get(fID) splots = [] for plot in fig.subplots: s = dv.Subplot() s.load(plot) s.parent = self.facsPlotPanel.figure splots.append(s) fig.subplots = splots currFigure = FigureStore.getSelectedFigure() self.facsPlotPanel.subplots = currFigure.subplots self.facsPlotPanel.SelectedSubplotIndex = currFigure.selectedSubplot self.facsPlotPanel.updateAxes(currFigure.axes, False) self.facsPlotPanel.updateSubplotGrid(currFigure.grid[0], currFigure.grid[1], True) self.chkLinked.Value = self.facsPlotPanel.CurrentSubplotLinked labels = DataStore.getCurrentDataSet().labels if DataStore.getCurrentDataSet() is not None else [] self.updateAxesList(labels, currFigure.axes) self.treeCtrlPanel.updateTree() self.statusbar.SetStatusText("Project loaded from %s" % dlg.Path, 0) dlg.Destroy()
def OnEditChannelNames(self, event): """ Allow users to modify the descriptors for each channel (dimension) """ fcData = DataStore.getCurrentDataSet() if fcData is not None: dgridDlg = displayDialogs.SampleDataDisplayDialog(self, fcData.data[0:10,:], fcData.labels, 'Edit Channel Labels', False, False) if (dgridDlg.ShowModal() == wx.ID_OK): # reassign FacsData instance labels for fcd in DataStore.getData().values(): labels = [item[1] for item in sorted(dgridDlg.ColumnLabels.iteritems(), key=itemgetter(0))] fcd.labels = labels # update channel selection cbxs self.updateAxesList(labels, self.facsPlotPanel.SelectedAxes) # refresh plot window self.facsPlotPanel.draw() dgridDlg.Destroy() else: wx.MessageBox("There are no data currently loaded.", "Error", wx.OK | wx.ICON_ERROR)
def buildDataTree(self, parent, dataDict, visited): for dIndex, fData in dataDict.iteritems(): # add tree node for the FACS data set if fData.ID in visited: return child = self.tree.AppendItem(parent, fData.displayname) if (DataStore.getCurrentIndex() == dIndex): self.tree.SetItemBold(child, True) self.tree.SetPyData(child, (DATA_SET_ITEM, dIndex)) self.tree.SetItemImage(child, self.fldridx, wx.TreeItemIcon_Normal) self.tree.SetItemImage(child, self.fldropenidx, wx.TreeItemIcon_Expanded) # add nodes for all the clusterings of the current data set for cIndex in fData.clustering: clust = self.tree.AppendItem(child, cluster.methods.getStringRepr(fData.methodIDs[cIndex]) + " " + str(cIndex+1)) if ((fData.selectedClustering == cIndex) and (fData.ID == DataStore.getCurrentIndex())): self.tree.SetItemBold(clust, True) toolTip = clusteringInfo(fData, cIndex) self.tree.SetPyData(clust, (DATA_SET_ITEM, dIndex, cIndex, toolTip)) #(data index, cluster index, tooltip) self.tree.SetItemImage(clust, self.fldridx, wx.TreeItemIcon_Normal) self.tree.SetItemImage(clust, self.fldropenidx, wx.TreeItemIcon_Expanded) # set clustering options for line in toolTip.split('\n'): if (line != ''): info = self.tree.AppendItem(clust, line) self.tree.SetPyData(info, None) if (fData.infoExpanded[cIndex]): self.tree.Expand(clust) # recursive call to build the tree for any children visited.append(fData.ID) self.buildDataTree(child, dict([(i,DataStore.getData()[i]) for i in fData.children]), visited) if (fData.nodeExpanded and self.tree.GetChildrenCount(child) > 0): self.tree.Expand(child)
def saveState(dir, filename): """ Save a representation of the system state: All the loaded data sets, their clusterings, any transformations or analyses (future), and all plots. The state is saved in JSON format based on a dict of the following form: data: list of IDs binfile: the filename of the binary file used to store all the actual data data-dID: dict of settings belonging to a FacsData instance clust-dID-cID: a dict of attributes belonging to a clustering figures: list of figureID strings fig-ID: A dict for each figure keyed on the ID. The subplot attribute here is replaced with a list of fig-ID-p-ID strings for locating subplot dicts fig-ID-p-ID: A dict for each subplot in each figure keyed on fig ID and plot ID. current-data: data ID current-figure: figure ID """ store = shelve.open(os.path.join(dir, filename)) #store = dbopen(os.path.join(dir, filename), 'c', format='csv') # The actual numeric data will be stored in a separate binary file using # the numpy savez() method allowing for efficient storage/retrieval of data binfile = '%s.npz' % filename bindata = {} store['data'] = DataStore.getData().keys() store['binfile'] = binfile for dID in DataStore.getData(): fdata = DataStore.get(dID) dStr = 'data-%i' % dID dfname = fdata.filename if (fdata.filename is not '') else binfile bindata[dStr] = fdata.data store[dStr] = {'filename': dfname, 'displayname': fdata.displayname, 'labels': fdata.labels, 'annotations': fdata.annotations, 'analysis': fdata.analysis, 'ID': fdata.ID, 'parent': fdata.parent, 'children': fdata.children, 'selDims': fdata.selDims, 'clustering': fdata.clustering.keys(), 'nodeExpanded': fdata.nodeExpanded, 'selectedClustering': fdata.selectedClustering} # clusterings for cID in fdata.clustering: cStr = 'clust-%i-%i' % (dID, cID) csett = {'method': fdata.methodIDs[cID], 'opts': fdata.clusteringOpts[cID], 'clusteringSelDims': fdata.clusteringSelDims[cID], 'infoExpanded': fdata.infoExpanded[cID]} store[cStr] = csett bindata[cStr] = fdata.clustering[cID] # figures sfigs = [] for figID in FigureStore.getFigures(): fig = FigureStore.get(figID) fStr = 'fig-%i' % figID d = dict(fig.__dict__) splots = packSubplots(store, figID, fig.subplots) d['subplots'] = splots store[fStr] = d sfigs.append(fStr) store['figures'] = list(sfigs) # other store['current-data'] = DataStore.getCurrentIndex() store['current-figure'] = FigureStore.getSelectedIndex() # write out settings data store.close() # write out numeric data to binary file np.savez(os.path.join(dir, binfile), **bindata)