def ifaceTransformChanged(self, iface): # imaging device moved; update viewport and tracked group. # This is only used when the camera is not running-- # if the camera is running, then this is taken care of in drawFrame to # ensure that the image remains stationary on screen. prof = Profiler() if not self.cam.isRunning(): tr = pg.SRTTransform(self.cam.globalTransform()) self.updateTransform(tr)
def newFrame(self, iface, frame): #sys.stdout.write('+') if not self.roiPlotCheck.isChecked(): return imageItem = iface.getImageItem() prof = Profiler('CameraWindow.addPlotFrame', disabled=True) if imageItem.width() is None: return ## Get rid of old frames minTime = None now = pg.time() #if len(self.frameBuffer) > 0: #while len(self.frameBuffer) > 0 and self.frameBuffer[0][1]['time'] < (now-self.ui.spinROITime.value()): #self.frameBuffer.pop(0) for r in self.ROIs: #print " >>", r['times'], now, frame[1]['time'], self.ui.spinROITime.value(), now-self.ui.spinROITime.value() while len(r['times']) > 0 and r['times'][0] < (now-self.roiTimeSpin.value()): r['times'].pop(0) r['vals'].pop(0) #print " <<", r['times'] if len(r['times']) > 0 and (minTime is None or r['times'][0] < minTime): minTime = r['times'][0] if minTime is None: minTime = frame.info()['time'] prof.mark('remove old frames') ## add new frame draw = False if self.lastPlotTime is None or now - self.lastPlotTime > 0.05: draw = True self.lastPlotTime = now for r in self.ROIs: d = r['roi'].getArrayRegion(frame.data(), imageItem, axes=(0,1)) prof.mark('get array rgn') if d is None: continue if d.size < 1: val = 0 else: val = d.mean() r['vals'].append(val) r['times'].append(frame.info()['time']) prof.mark('append') if draw: r['plot'].setData(np.array(r['times'])-minTime, r['vals']) prof.mark('draw') prof.finish()
def newFrame(self, iface, frame): """New frame has arrived; update ROI plot if needed. """ if not self.roiPlotCheck.isChecked(): return imageItem = iface.getImageItem() prof = Profiler('CameraWindow.addPlotFrame', disabled=True) if imageItem.width() is None: return # Get rid of old frames minTime = None now = pg.time() for r in self.ROIs: while len(r['times']) > 0 and r['times'][0] < (now-self.roiTimeSpin.value()): r['times'].pop(0) r['vals'].pop(0) if len(r['times']) > 0 and (minTime is None or r['times'][0] < minTime): minTime = r['times'][0] if minTime is None: minTime = frame.info()['time'] prof.mark('remove old frames') # add new frame draw = False if self.lastPlotTime is None or now - self.lastPlotTime > 0.05: draw = True self.lastPlotTime = now for r in self.ROIs: if isinstance(r['roi'], pg.graphicsItems.ROI.RulerROI): continue d = r['roi'].getArrayRegion(frame.data(), imageItem, axes=(0,1)) prof.mark('get array rgn') if d is None: continue if d.size < 1: val = 0 else: val = d.mean() r['vals'].append(val) r['times'].append(frame.info()['time']) prof.mark('append') if draw: r['plot'].setData(np.array(r['times'])-minTime, r['vals']) prof.mark('draw') prof.finish()
def drawFrame(self): if self.hasQuit: return #sys.stdout.write('+') try: ## If we last drew a frame < 1/30s ago, return. t = ptime.time() if (self.lastDrawTime is not None) and (t - self.lastDrawTime < .033333): #sys.stdout.write('-') return ## if there is no new frame and no controls have changed, just exit if not self.updateFrame and self.nextFrame is None: #sys.stdout.write('-') return self.updateFrame = False ## If there are no new frames and no previous frames, then there is nothing to draw. if self.currentFrame is None and self.nextFrame is None: #sys.stdout.write('-') return prof = Profiler() ## We will now draw a new frame (even if the frame is unchanged) if self.lastDrawTime is not None: fps = 1.0 / (t - self.lastDrawTime) self.ui.displayFpsLabel.setValue(fps) self.lastDrawTime = t prof() ## Handle the next available frame, if there is one. if self.nextFrame is not None: self.currentFrame = self.nextFrame self.nextFrame = None data = self.currentFrame.data() info = self.currentFrame.info() prof() ## divide the background out of the current frame if needed if self.ui.divideBgBtn.isChecked(): bg = self.getBackgroundFrame() if bg is not None and bg.shape == data.shape: data = data / bg elif self.ui.subtractBgBtn.isChecked(): bg = self.getBackgroundFrame() if bg is not None and bg.shape == data.shape: data = data - bg prof() ## Set new levels if auto gain is enabled if self.ui.btnAutoGain.isChecked(): cw = self.ui.spinAutoGainCenterWeight.value() (w,h) = data.shape center = data[w/2.-w/6.:w/2.+w/6., h/2.-h/6.:h/2.+h/6.] minVal = data.min() * (1.0-cw) + center.min() * cw maxVal = data.max() * (1.0-cw) + center.max() * cw ## If there is inf/nan in the image, strip it out before computing min/max if any([np.isnan(minVal), np.isinf(minVal), np.isnan(minVal), np.isinf(minVal)]): nanMask = np.isnan(data) infMask = np.isinf(data) valid = data[~nanMask * ~infMask] minVal = valid.min() * (1.0-cw) + center.min() * cw maxVal = valid.max() * (1.0-cw) + center.max() * cw ## Smooth min/max range to avoid noise if self.lastMinMax is None: minVal = minVal maxVal = maxVal else: s = 1.0 - 1.0 / (self.ui.spinAutoGainSpeed.value()+1.0) minVal = self.lastMinMax[0] * s + minVal * (1.0-s) maxVal = self.lastMinMax[1] * s + maxVal * (1.0-s) self.lastMinMax = [minVal, maxVal] ## and convert fraction of previous range into new levels bl = self.autoGainLevels[0] * (maxVal-minVal) + minVal wl = self.autoGainLevels[1] * (maxVal-minVal) + minVal self.ignoreLevelChange = True try: self.ui.histogram.setLevels(bl, wl) self.ui.histogram.setHistogramRange(minVal, maxVal, padding=0.05) finally: self.ignoreLevelChange = False prof() ## update image in viewport self.imageItem.updateImage(data)#, levels=[bl, wl]) self.imageItem.setOpacity(self.alpha) self.imageItem.setTransform(self.currentFrame.frameTransform().as2D()) prof() ## Update viewport to correct for scope movement/scaling tr = pg.SRTTransform(self.currentFrame.cameraTransform()) self.updateTransform(tr) self.imageItemGroup.setTransform(tr) prof() prof() prof.finish() except: printExc('Error while drawing new frames:') finally: pass
def storeToDB(self): ## collect list of cells and scans under this slice, ## read all positions with userTransform corrections prof = Profiler("Atlas.storeToDB", disabled=True) loaded = self.host.getLoadedFiles() cells = [] prots = [] for f in loaded: if not f.isDir() or not f.isGrandchildOf(self.sliceDir): continue if self.dataModel.dirType(f) == 'Cell': info = f.info() if 'userTransform' not in info: continue cells.append((f, info['userTransform']['pos'])) elif self.dataModel.dirType(f) == 'Protocol': info = f.info() scanInfo = info.get('Scanner', None) if scanInfo is None: continue tr = pg.SRTTransform(info.get('userTransform', None)) pos = tr.map(*scanInfo['position']) prots.append((f, pos)) elif self.dataModel.dirType(f) == 'ProtocolSequence': info = f.info() tr = pg.SRTTransform(info.get('userTransform', None)) for subName in f.subDirs(): subf = f[subName] scanInfo = subf.info().get('Scanner', None) if scanInfo is None: continue pos = tr.map(*scanInfo['position']) prots.append((subf, pos)) prof.mark("made list of positions") for ident, dirType, positions in [('_cell', 'Cell', cells), ('_protocol', 'Protocol', prots)]: ## map positions, build data tables data, fields = self.generateDataArray(positions, dirType) prof.mark("got data arrays for %s" % dirType) #dirColumn = dirType + 'Dir' #data = np.empty(len(positions), dtype=[('SliceDir', object), (dirColumn, object), ('right', float), ('anterior', float), ('dorsal', float)]) #for i in range(len(positions)): #dh, pos = positions[i] #mapped = self.atlas.mapToAtlas(pg.Point(pos)) ##print dh, pos ##print " right:", mapped.x() ##print " anter:", mapped.y() ##print " dorsl:", mapped.z() #data[i] = (self.sliceDir, dh, mapped.x(), mapped.y(), mapped.z()) ## write to DB db = self.ui.dbWidget.getDb() prof.mark('got db') table = self.ui.dbWidget.getTableName(self.atlas.DBIdentity + ident) prof.mark('got table') #fields = collections.OrderedDict([ #('SliceDir', 'directory:Slice'), #(dirColumn, 'directory:'+dirType), #('right', 'real'), #('anterior', 'real'), #('dorsal', 'real'), #]) ## Make sure target table exists and has correct columns db.checkTable(table, owner=self.atlas.DBIdentity + ident, columns=fields, create=True) prof.mark('checked table') ## delete old -- This is the slow part! old = db.select(table, where={'SliceDir': self.sliceDir}, toArray=True) if old is not None: ## only do deleting if there is already data stored for this slice -- try to speed things up for source in set(data[dirType + 'Dir']): if source in old[ dirType + 'Dir']: ## check that source is in the old data before we delete it - try to speed things up db.delete(table, where={dirType + 'Dir': source}) prof.mark('deleted old data') ## write new db.insert(table, data) prof.mark("added %s data to db" % dirType) prof.finish()
def storeToDB(self): ## collect list of cells and scans under this slice, ## read all positions with userTransform corrections prof = Profiler("Atlas.storeToDB", disabled=True) loaded = self.host.getLoadedFiles() cells = [] prots = [] for f in loaded: if not f.isDir() or not f.isGrandchildOf(self.sliceDir): continue if self.dataModel.dirType(f) == 'Cell': info = f.info() if 'userTransform' not in info: continue cells.append((f, info['userTransform']['pos'])) elif self.dataModel.dirType(f) == 'Protocol': info = f.info() scanInfo = info.get('Scanner', None) if scanInfo is None: continue tr = pg.SRTTransform(info.get('userTransform', None)) pos = tr.map(*scanInfo['position']) prots.append((f, pos)) elif self.dataModel.dirType(f) == 'ProtocolSequence': info = f.info() tr = pg.SRTTransform(info.get('userTransform', None)) for subName in f.subDirs(): subf = f[subName] scanInfo = subf.info().get('Scanner', None) if scanInfo is None: continue pos = tr.map(*scanInfo['position']) prots.append((subf, pos)) prof.mark("made list of positions") for ident, dirType, positions in [('_cell', 'Cell', cells), ('_protocol', 'Protocol', prots)]: ## map positions, build data tables data, fields = self.generateDataArray(positions, dirType) prof.mark("got data arrays for %s" %dirType) #dirColumn = dirType + 'Dir' #data = np.empty(len(positions), dtype=[('SliceDir', object), (dirColumn, object), ('right', float), ('anterior', float), ('dorsal', float)]) #for i in range(len(positions)): #dh, pos = positions[i] #mapped = self.atlas.mapToAtlas(pg.Point(pos)) ##print dh, pos ##print " right:", mapped.x() ##print " anter:", mapped.y() ##print " dorsl:", mapped.z() #data[i] = (self.sliceDir, dh, mapped.x(), mapped.y(), mapped.z()) ## write to DB db = self.ui.dbWidget.getDb() prof.mark('got db') table = self.ui.dbWidget.getTableName(self.atlas.DBIdentity+ident) prof.mark('got table') #fields = collections.OrderedDict([ #('SliceDir', 'directory:Slice'), #(dirColumn, 'directory:'+dirType), #('right', 'real'), #('anterior', 'real'), #('dorsal', 'real'), #]) ## Make sure target table exists and has correct columns db.checkTable(table, owner=self.atlas.DBIdentity+ident, columns=fields, create=True) prof.mark('checked table') ## delete old -- This is the slow part! old = db.select(table, where={'SliceDir':self.sliceDir}, toArray=True) if old is not None: ## only do deleting if there is already data stored for this slice -- try to speed things up for source in set(data[dirType+'Dir']): if source in old[dirType+'Dir']: ## check that source is in the old data before we delete it - try to speed things up db.delete(table, where={dirType+'Dir': source}) prof.mark('deleted old data') ## write new db.insert(table, data) prof.mark("added %s data to db" %dirType) prof.finish()
def generateDataArray(self, positions, dirType): prof = Profiler("A1Atlas.generateDataArray", disabled=True) if self.atlas.state is None: self.saveState() prof.mark('saved atlas state') dirColumn = dirType + 'Dir' if dirType == 'Protocol': data = np.empty(len(positions), dtype=[('SliceDir', object), (dirColumn, object), #('layer', float), #('depth', float), ('yPosSlice', float), ('yPosCell', float), ('percentDepth', float), ('xPosSlice', float), ('xPosCell', float), ('modXPosSlice', float), ('modXPosCell', float)]) fields = collections.OrderedDict([ ('SliceDir', 'directory:Slice'), (dirColumn, 'directory:'+dirType), ('yPosSlice', 'real'), ('yPosCell', 'real'), ('percentDepth', 'real'), ('xPosSlice', 'real'), ('xPosCell', 'real'), ('modXPosSlice', 'real'), ('modXPosCell', 'real')]) prof.mark("defined Protocol data array") for i in range(len(positions)): dh, pos = positions[i] cellPos = self.dataModel.getCellInfo(dh)['userTransform']['pos'] mapped = self.atlas.mapToAtlas(pg.Point(pos)) ## needs to return %depth and modXPosSlice #data[i] = (self.sliceDir, dh, mapped.x(), mapped.y(), mapped.z()) data[i]['SliceDir'] = self.sliceDir data[i][dirColumn] = dh data[i]['yPosSlice'] = pos[1] data[i]['yPosCell'] = pos[1]-cellPos[1] data[i]['percentDepth'] = mapped[1] data[i]['xPosSlice'] = pos[0] data[i]['xPosCell'] = pos[0]-cellPos[0] data[i]['modXPosSlice'] = mapped[0] data[i]['modXPosCell'] = mapped[0]-self.atlas.mapToAtlas(pg.Point(cellPos))[0] prof.mark("filled protocol data array") elif dirType == 'Cell': data = np.empty(len(positions), dtype=[('SliceDir', object), (dirColumn, object), #('layer', float), #('depth', float), ('yPosSlice', float), #('yPosCell', float), ('percentDepth', float), ('xPosSlice', float), #('xPosCell', float), ('modXPosSlice', float), #('modXPosCell', float) ]) fields = collections.OrderedDict([ ('SliceDir', 'directory:Slice'), (dirColumn, 'directory:'+dirType), ('yPosSlice', 'real'), ('percentDepth', 'real'), ('xPosSlice', 'real'), ('modXPosSlice', 'real')]) prof.mark("defined cell data array") for i in range(len(positions)): dh, pos = positions[i] #cellPos = self.dataModel.getCellInfo(dh)['pos'] mapped = self.atlas.mapToAtlas(pg.Point(pos)) ## needs to return %depth and modXPosSlice #data[i] = (self.sliceDir, dh, mapped.x(), mapped.y(), mapped.z()) data[i]['SliceDir'] = self.sliceDir data[i][dirColumn] = dh data[i]['yPosSlice'] = pos[1] #data['yPosCell'] = pos[1]-cellPos[1] data[i]['percentDepth'] = mapped[1] data[i]['xPosSlice'] = pos[0] #data['xPosCell'] = pos[0]-cellPos[0] data[i]['modXPosSlice'] = mapped[0] #data['modXPosCell'] = mapped[0]-self.atlas.mapToAtlas(pg.Point(cellPos))[0] prof.mark("filled cell data array") else: prof.finish() raise Exception("Not sure how to structure data array for dirType=%s"%dirType) prof.finish() return data, fields