Exemple #1
0
 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)
Exemple #2
0
 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()
Exemple #3
0
 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()
Exemple #4
0
    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
Exemple #5
0
    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()
Exemple #6
0
 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()
Exemple #7
0
 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