def addLabel(info=None): global labelInfo create = False if info is None: create = True l = ui.labelSpin.value() if l in labelInfo: return info = { 'visible': True, 'name': 'label', 'color': pg.intColor(len(labelInfo), 16), 'id': l } else: info = info.copy() info['color'] = pg.mkColor(info['color']) l = info['id'] item = Qt.QTreeWidgetItem([str(l), info['name'], '']) item.setFlags(item.flags() | Qt.Qt.ItemIsEditable | Qt.Qt.ItemIsUserCheckable) if info['visible']: item.setCheckState(0, Qt.Qt.Checked) else: item.setCheckState(0, Qt.Qt.Unchecked) btn = pg.ColorButton(color=info['color']) ui.labelTree.addTopLevelItem(item) ui.labelTree.setItemWidget(item, 2, btn) labelInfo[l] = {'item': item, 'btn': btn} btn.sigColorChanged.connect(itemChanged) btn.sigColorChanging.connect(imageChanged) if create: writeMeta()
def addROI(self, roiType): pen = pg.mkPen(pg.intColor(len(self.ROIs))) center = self.view.viewRect().center() #print 'camerawindow.py: addROI:: ', self.view.viewPixelSize() size = [x * 50 for x in self.view.viewPixelSize()] if roiType == 'rect': roi = PlotROI(center, size) elif roiType == 'ellipse': roi = pg.EllipseROI(center, size, removable=True) elif roiType == 'polygon': pts = [ center, center + pg.Point(0, size[1]), center + pg.Point(size[0], 0) ] roi = pg.PolyLineROI(pts, closed=True, removable=True) elif roiType == 'ruler': pts = [center, center + pg.Point(size[0], size[1])] roi = RulerROI(pts, removable=True) else: raise ValueError("Invalid ROI type %s" % roiType) roi.setZValue(40000) roi.setPen(pen) self.view.addItem(roi) plot = self.roiPlot.plot(pen=pen) self.ROIs.append({'roi': roi, 'plot': plot, 'vals': [], 'times': []}) roi.sigRemoveRequested.connect(self.removeROI)
def addLabel(info=None): global labelInfo create = False if info is None: create = True l = ui.labelSpin.value() if l in labelInfo: return info = { 'visible': True, 'name': 'label', 'color': pg.intColor(len(labelInfo), 16), 'id': l } else: info = info.copy() info['color'] = pg.mkColor(info['color']) l = info['id'] item = QtGui.QTreeWidgetItem([str(l), info['name'], '']) item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsUserCheckable) if info['visible']: item.setCheckState(0, QtCore.Qt.Checked) else: item.setCheckState(0, QtCore.Qt.Unchecked) btn = pg.ColorButton(color=info['color']) ui.labelTree.addTopLevelItem(item) ui.labelTree.setItemWidget(item, 2, btn) labelInfo[l] = {'item': item, 'btn': btn} btn.sigColorChanged.connect(itemChanged) btn.sigColorChanging.connect(imageChanged) if create: writeMeta()
def redisplayData(self, points): ## data must be [(scan, fh, <event time>), ...] #raise Exception('blah') #print points try: QtGui.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.WaitCursor)) plot = self.getElement("Data Plot") plot.clear() eTable = self.getElement("Event Table") sTable = self.getElement("Stats") #num = len(point.data) num = len(points) statList = [] evList = [] for i in range(num): color = pg.intColor(i, num) #scan, fh = point.data[i] try: scan, fh = points[i][:2] except: print points[i] raise if len(points[i]) == 3: evTime = points[i][2] else: evTime = None scan.displayData(fh, plot, color, evTime) ## show stats stats = scan.getStats(fh.parent()) statList.append(stats) events = scan.getEvents(fh)['events'] if len(events) > 0: evList.append(events) sTable.setData(statList) if len(evList) > 0: try: eTable.setData(np.concatenate(evList)) except: for i in range(1,len(evList)): if len(evList[i].dtype) != len(evList[i-1].dtype): print "Cannot concatenate; event lists have different dtypes:" print evList[i].dtype print evList[i-1].dtype else: for j in range(len(evList[i].dtype)): if evList[i-1].dtype[j] != evList[i].dtype[j]: for l in evList: print l print "Warning: can not concatenate--field '%s' has inconsistent types %s, %s (data printed above)" % (evList[i].dtype.names[j], str(evList[i-1].dtype[j]), str(evList[i].dtype[j])) raise finally: QtGui.QApplication.restoreOverrideCursor()
def addROI(self): pen = pg.mkPen(pg.intColor(len(self.ROIs))) center = self.view.viewRect().center() #print 'camerawindow.py: addROI:: ', self.view.viewPixelSize() size = [x*50 for x in self.view.viewPixelSize()] roi = PlotROI(center, size) roi.setZValue(40000) roi.setPen(pen) self.view.addItem(roi) plot = self.roiPlot.plot(pen=pen) self.ROIs.append({'roi': roi, 'plot': plot, 'vals': [], 'times': []}) roi.sigRemoveRequested.connect(self.removeROI)
def updateTracesPlot(self): """Update the Trace display plot to show the traces corresponding to the timestamps selected by the region in the experiment plot.""" rgn = self.traceSelectRgn.getRegion() self.tracesPlot.clear() ### plot all the traces with timestamps within the selected region (according to self.traceSelectRgn) data = self.traces[(self.traces['timestamp'] > rgn[0] + self.expStart) * (self.traces['timestamp'] < rgn[1] + self.expStart)] for i, d in enumerate(data['data']): self.tracesPlot.plot(d['primary'], pen=pg.intColor(i, len(data))) if len(data) > 0: self.flowchart.setInput(dataIn=data[0]['fileHandle'])
def plotData(): rate = 1e3 nPts = 100 plot.clear() params = {} paramSpace = sg.listSequences() for k in paramSpace: params[k] = range(len(paramSpace[k])) global seqPlots seqPlots = [] SequenceRunner.runSequence(lambda p: seqPlots.append(sg.getSingle(rate, nPts, p)), params, params.keys()) for i, w in enumerate(seqPlots): if w is not None: plot.plot(w, pen=pg.intColor(i, len(seqPlots)*1.5)) data = sg.getSingle(rate, nPts) plot.plot(data, pen=pg.mkPen('w', width=2))
def plotData(): rate = 1e3 nPts = 100 plot.clear() params = {} paramSpace = sg.listSequences() for k in paramSpace: params[k] = range(len(paramSpace[k])) global seqPlots seqPlots = [] SequenceRunner.runSequence( lambda p: seqPlots.append(sg.getSingle(rate, nPts, p)), params, list(params.keys())) for i, w in enumerate(seqPlots): if w is not None: plot.plot(w, pen=pg.intColor(i, len(seqPlots) * 1.5)) data = sg.getSingle(rate, nPts) plot.plot(data, pen=pg.mkPen('w', width=2))
def _load_data(self, seqDir): man = getManager() model = man.dataModel # read all image data self.img_data = model.buildSequenceArray( seqDir, lambda dh: dh['Camera']['frames.ma'].read(), join=False).asarray() seqParams = list(model.listSequenceParams(seqDir).items()) if self.img_data.ndim == 1: self.img_data = self.img_data[np.newaxis, :] seqParams.insert(0, (None, [0])) transpose = seqParams[0][0] == ('protocol', 'repetitions') if transpose: self.img_data = np.swapaxes(self.img_data, 0, 1) seqParams = seqParams[::-1] self.seqParams = seqParams if seqParams[0][0] is None: self.seqColors = [pg.mkColor('w')] else: nSeq = len(seqParams[0][1]) if nSeq == 2: # Special case: add in difference between two sequence trials seqParams[0] = (seqParams[0][0], list(seqParams[0][1]) + [np.mean(seqParams[0][1])]) nSeq = 3 img_data = np.empty((3, ) + self.img_data.shape[1:], dtype=self.img_data.dtype) img_data[:2] = self.img_data for i in range(img_data.shape[1]): minlen = min(self.img_data[0, i].shape[0], self.img_data[1, i].shape[0]) img_data[2, i] = self.img_data[0, i][:minlen].copy() img_data[2, i]._data = self.img_data[ 0, i][:minlen].asarray().astype( 'float') - self.img_data[1, i][:minlen].asarray() self.img_data = img_data self.seqColors = [pg.intColor(i, nSeq * 1.6) for i in range(nSeq)] # cull out truncated recordings :( self.img_data = [[ d['Time':0:200e-3] for d in row if d.xvals('Time')[-1] > 150e-3 ] for row in self.img_data] # crop / concatenate img_len = min( [min([d.shape[0] for d in row]) for row in self.img_data]) self.img_data = [[d[:img_len] for d in row] for row in self.img_data] self.img_arrays = [ np.concatenate([d.asarray()[np.newaxis, ...] for d in row], axis=0) for row in self.img_data ] # average self.img_mean = [img_arr.mean(axis=0) for img_arr in self.img_arrays] for p in self.clamp_plots: self.plt2.removeItem(p) # read all clamp data first_subdir = seqDir[seqDir.ls()[0]] clamp_name = 'Clamp1' if not first_subdir[clamp_name + '.ma'].exists(): clamp_name = 'Clamp2' clamp_file = first_subdir[clamp_name + '.ma'] if clamp_file.exists(): self.clamp_mode = model.getClampMode(clamp_file) chan = 'command' if self.clamp_mode == 'VC' else 'primary' self.clamp_data = model.buildSequenceArray( seqDir, lambda dh: dh[clamp_name + '.ma'].read()['Channel':chan], join=False).asarray() if self.clamp_data.ndim == 1: self.clamp_data = self.clamp_data[np.newaxis, :] if transpose: self.clamp_data = np.swapaxes(self.clamp_data, 0, 1) self.plt2.setLabels(left=('Vm', 'V')) for i in range(self.clamp_data.shape[0]): for j in range(self.clamp_data.shape[1]): trace = self.clamp_data[i, j] pen = self.seqColors[i] p = self.plt2.plot(trace.xvals('Time'), trace.asarray(), antialias=True, pen=pen) self.clamp_plots.append(p) self.plt2.show() else: self.clamp_mode = None self.plt2.hide() self.img_t = self.img_data[0][0].xvals('Time') self.img1.setImage(self.img_mean[-1].mean(axis=0)) self.roi_changed(None) self.time_rgn_changed(None) self.update_sequence_analysis()
def _load_data(self, seqDir): man = getManager() model = man.dataModel # read all image data self.img_data = model.buildSequenceArray( seqDir, lambda dh: dh['Camera']['frames.ma'].read(), join=False).asarray() seqParams = list(model.listSequenceParams(seqDir).items()) if self.img_data.ndim == 1: self.img_data = self.img_data[np.newaxis, :] seqParams.insert(0, (None, [0])) transpose = seqParams[0][0] == ('protocol', 'repetitions') if transpose: self.img_data = np.swapaxes(self.img_data, 0, 1) seqParams = seqParams[::-1] self.seqParams = seqParams if seqParams[0][0] is None: self.seqColors = [pg.mkColor('w')] else: nSeq = len(seqParams[0][1]) if nSeq == 2: # Special case: add in difference between two sequence trials seqParams[0] = (seqParams[0][0], list(seqParams[0][1]) + [np.mean(seqParams[0][1])]) nSeq = 3 img_data = np.empty((3,) + self.img_data.shape[1:], dtype=self.img_data.dtype) img_data[:2] = self.img_data for i in range(img_data.shape[1]): minlen = min(self.img_data[0,i].shape[0], self.img_data[1,i].shape[0]) img_data[2,i] = self.img_data[0,i][:minlen].copy() img_data[2,i]._data = self.img_data[0,i][:minlen].asarray().astype('float') - self.img_data[1,i][:minlen].asarray() self.img_data = img_data self.seqColors = [pg.intColor(i, nSeq*1.6) for i in range(nSeq)] # cull out truncated recordings :( self.img_data = [[d['Time':0:200e-3] for d in row if d.xvals('Time')[-1] > 150e-3] for row in self.img_data] # crop / concatenate img_len = min([min([d.shape[0] for d in row]) for row in self.img_data]) self.img_data = [[d[:img_len] for d in row] for row in self.img_data] self.img_arrays = [np.concatenate([d.asarray()[np.newaxis, ...] for d in row], axis=0) for row in self.img_data] # average self.img_mean = [img_arr.mean(axis=0) for img_arr in self.img_arrays] for p in self.clamp_plots: self.plt2.removeItem(p) # read all clamp data first_subdir = seqDir[seqDir.ls()[0]] clamp_name = 'Clamp1' if not first_subdir[clamp_name + '.ma'].exists(): clamp_name = 'Clamp2' clamp_file = first_subdir[clamp_name + '.ma'] if clamp_file.exists(): self.clamp_mode = model.getClampMode(clamp_file) chan = 'command' if self.clamp_mode == 'VC' else 'primary' self.clamp_data = model.buildSequenceArray( seqDir, lambda dh: dh[clamp_name + '.ma'].read()['Channel': chan], join=False).asarray() if self.clamp_data.ndim == 1: self.clamp_data = self.clamp_data[np.newaxis, :] if transpose: self.clamp_data = np.swapaxes(self.clamp_data, 0, 1) self.plt2.setLabels(left=('Vm', 'V')) for i in range(self.clamp_data.shape[0]): for j in range(self.clamp_data.shape[1]): trace = self.clamp_data[i,j] pen = self.seqColors[i] p = self.plt2.plot(trace.xvals('Time'), trace.asarray(), antialias=True, pen=pen) self.clamp_plots.append(p) self.plt2.show() else: self.clamp_mode = None self.plt2.hide() self.img_t = self.img_data[0][0].xvals('Time') self.img1.setImage(self.img_mean[-1].mean(axis=0)) self.roi_changed(None) self.time_rgn_changed(None) self.update_sequence_analysis()
def updateProfiles(self): #if not self.analyzeBtn.isChecked(): #return plots = self.getElement('profiles'), self.getElement('profile fits') for plot in plots: plot.clear() plot.setLabel('bottom', 'distance', units='m') width, height = self.normData.shape xVals = np.linspace(0, self.px[0] * width, width) fits = [] def slopeGaussian(v, x): ## gaussian + slope return fn.gaussian(v[:4], x) + v[4] * x def gaussError( v, x, y): ## center-weighted error functionfor sloped gaussian err = abs(y - slopeGaussian(v, x)) v2 = [2.0, v[1], v[2] * 0.3, 1.0, 0.0] return err * slopeGaussian(v2, x) with pg.ProgressDialog("Processing..", 0, height - 1, cancelText=None) as dlg: for i in range(height): row = self.normData[:, i] guess = [ row.max() - row.min(), xVals[int(width / 2)], self.px[0] * 3, row.max(), 0.0 ] #fit = fn.fitGaussian(xVals=xVals, yVals=row, guess=guess)[0] #fit = fn.fit(slopeGaussian, xVals=xVals, yVals=row, guess=guess)[0] fit = scipy.optimize.leastsq(gaussError, guess, args=(xVals, row))[0] fit[2] = abs(fit[2]) dist = fit[1] / (self.px[0] * width / 2.) #print fit, dist ## sanity check on fit if abs(dist - 1) > 0.5 or (0.5 < fit[3] / np.median(row) > 2.0): #print "rejected:", fit, fit[3]/np.median(row), self.px[0]*width/2. #fit = guess[:] #fit[0] = 0 fit = [0, 0, 0, 0, 0] else: # round 2: eliminate anomalous points and re-fit fitCurve = slopeGaussian(fit, xVals) diff = row - fitCurve std = diff.std() mask = abs(diff) < std * 1.5 x2 = xVals[mask] y2 = row[mask] fit = fn.fit(slopeGaussian, xVals=x2, yVals=y2, guess=fit)[0] fits.append(fit) dlg += 1 if dlg.wasCanceled(): raise Exception("Processing canceled by user") for i in range(len(fits)): ## plot in reverse order pen = pg.intColor(height - i, height * 1.4) plots[0].plot(y=self.normData[:, -1 - i], x=xVals, pen=pen) plots[1].plot(y=slopeGaussian(fits[-1 - i], xVals), x=xVals, pen=pen) yVals = np.linspace(0, self.px[0] * height, height) arr = np.array(fits) info = [{ 'name': 'depth', 'units': 'm', 'values': yVals }, { 'name': 'fitParams', 'cols': [ { 'name': 'Amplitude' }, { 'name': 'X Offset' }, { 'name': 'Sigma', 'units': 'm' }, { 'name': 'Y Offset' }, { 'name': 'Slope' }, ] }, { 'sourceImage': self.fileHandle.name(), 'dataRegion': self.dataRgn.saveState(), 'backgroundRegion': self.bgRgn.saveState(), 'description': """ The source image was normalized for background fluorescence, then each row was fit to a sloped gaussian function: v[0] * np.exp(-((x-v[1])**2) / (2 * v[2]**2)) + v[3] + v[4] * x The fit parameters v[0..4] for each image row are stored in the columns of this data set. """ }] #print info self.data = MetaArray(arr, info=info) self.showResults(self.data)
def redisplayData(self, points): ## data must be [(scan, fh, <event time>), ...] #raise Exception('blah') #print points try: QtGui.QApplication.setOverrideCursor( QtGui.QCursor(QtCore.Qt.WaitCursor)) plot = self.getElement("Data Plot") plot.clear() eTable = self.getElement("Event Table") sTable = self.getElement("Stats") #num = len(point.data) num = len(points) statList = [] evList = [] for i in range(num): color = pg.intColor(i, num) #scan, fh = point.data[i] try: scan, fh = points[i][:2] except: print points[i] raise if len(points[i]) == 3: evTime = points[i][2] else: evTime = None scan.displayData(fh, plot, color, evTime) ## show stats stats = scan.getStats(fh.parent()) statList.append(stats) events = scan.getEvents(fh)['events'] if len(events) > 0: evList.append(events) sTable.setData(statList) if len(evList) > 0: try: eTable.setData(np.concatenate(evList)) except: for i in range(1, len(evList)): if len(evList[i].dtype) != len(evList[i - 1].dtype): print "Cannot concatenate; event lists have different dtypes:" print evList[i].dtype print evList[i - 1].dtype else: for j in range(len(evList[i].dtype)): if evList[i - 1].dtype[j] != evList[i].dtype[j]: for l in evList: print l print "Warning: can not concatenate--field '%s' has inconsistent types %s, %s (data printed above)" % ( evList[i].dtype.names[j], str(evList[i - 1].dtype[j]), str(evList[i].dtype[j])) raise finally: QtGui.QApplication.restoreOverrideCursor()
def updateProfiles(self): #if not self.analyzeBtn.isChecked(): #return plots = self.getElement('profiles'), self.getElement('profile fits') for plot in plots: plot.clear() plot.setLabel('bottom', 'distance', units='m') width, height = self.normData.shape xVals = np.linspace(0, self.px[0]*width, width) fits = [] def slopeGaussian(v, x): ## gaussian + slope return fn.gaussian(v[:4], x) + v[4] * x def gaussError(v, x, y): ## center-weighted error functionfor sloped gaussian err = abs(y-slopeGaussian(v, x)) v2 = [2.0, v[1], v[2]*0.3, 1.0, 0.0] return err * slopeGaussian(v2, x) with pg.ProgressDialog("Processing..", 0, height-1, cancelText=None) as dlg: for i in range(height): row = self.normData[:, i] guess = [row.max()-row.min(), xVals[int(width/2)], self.px[0]*3, row.max(), 0.0] #fit = fn.fitGaussian(xVals=xVals, yVals=row, guess=guess)[0] #fit = fn.fit(slopeGaussian, xVals=xVals, yVals=row, guess=guess)[0] fit = scipy.optimize.leastsq(gaussError, guess, args=(xVals, row))[0] fit[2] = abs(fit[2]) dist = fit[1] / (self.px[0] * width / 2.) #print fit, dist ## sanity check on fit if abs(dist-1) > 0.5 or (0.5 < fit[3]/np.median(row) > 2.0): #print "rejected:", fit, fit[3]/np.median(row), self.px[0]*width/2. #fit = guess[:] #fit[0] = 0 fit = [0,0,0,0,0] else: # round 2: eliminate anomalous points and re-fit fitCurve = slopeGaussian(fit, xVals) diff = row - fitCurve std = diff.std() mask = abs(diff) < std * 1.5 x2 = xVals[mask] y2 = row[mask] fit = fn.fit(slopeGaussian, xVals=x2, yVals=y2, guess=fit)[0] fits.append(fit) dlg += 1 if dlg.wasCanceled(): raise Exception("Processing canceled by user") for i in range(len(fits)): ## plot in reverse order pen = pg.intColor(height-i, height*1.4) plots[0].plot(y=self.normData[:, -1-i], x=xVals, pen=pen) plots[1].plot(y=slopeGaussian(fits[-1-i], xVals), x=xVals, pen=pen) yVals = np.linspace(0, self.px[0]*height, height) arr = np.array(fits) info = [ {'name': 'depth', 'units': 'm', 'values': yVals}, {'name': 'fitParams', 'cols': [ {'name': 'Amplitude'}, {'name': 'X Offset'}, {'name': 'Sigma', 'units': 'm'}, {'name': 'Y Offset'}, {'name': 'Slope'}, ]}, { 'sourceImage': self.fileHandle.name(), 'dataRegion': self.dataRgn.saveState(), 'backgroundRegion': self.bgRgn.saveState(), 'description': """ The source image was normalized for background fluorescence, then each row was fit to a sloped gaussian function: v[0] * np.exp(-((x-v[1])**2) / (2 * v[2]**2)) + v[3] + v[4] * x The fit parameters v[0..4] for each image row are stored in the columns of this data set. """ } ] #print info self.data = MetaArray(arr, info=info) self.showResults(self.data)