Esempio n. 1
0
    def enumerateDevices(cls):
        """Generate a list of all Scientifica devices found in the system.

        Sets Scientifica.availableDevices to a dict of {name: port} pairs.

        This works by searching for USB serial devices with device IDs used by Scientifica
        (vid=0403, pid=6010) and sending a single serial request.
        """
        import serial.tools.list_ports
        coms = serial.tools.list_ports.comports()
        devs = {}
        for com, name, ident in coms:
            # several different ways this can appear:
            #  VID_0403+PID_6010
            #  VID_0403&PID_6010
            #  VID:PID=0403:6010
            if ('VID_0403' not in ident or 'PID_6010' not in ident) and '0403:6010' not in ident:
                continue
            com = cls.normalizePortName(com)
            if com in cls.openDevices:
                name = cls.openDevices[com].getDescription()
                devs[name] = com
            else:
                try:
                    s = Scientifica(port=com, ctrl_version=None)
                    devs[s.getDescription()] = com
                    s.close()
                except Exception:
                    printExc("Error while initializing Scientifica device at %s (the device at this port will not be available):" % com)

        cls.availableDevices = devs
Esempio n. 2
0
    def quit(self):
        if self.hasQuit:
            return

        try:
            self.recordThread.sigShowMessage.disconnect(self.showMessage)
            self.recordThread.finished.disconnect(self.recordThreadStopped)
            self.recordThread.sigRecordingFailed.disconnect(self.recordingFailed)
            self.recordThread.sigRecordingFinished.disconnect(self.recordFinished)
        except TypeError:
            pass

        try:
            self.cam.sigNewFrame.disconnect(self.newFrame)
            self.cam.sigCameraStopped.disconnect(self.cameraStopped)
            self.cam.sigCameraStarted.disconnect(self.cameraStarted)
            self.cam.sigShowMessage.disconnect(self.showMessage)
        except TypeError:
            pass

        self.hasQuit = True
        if self.cam.isRunning():
            self.cam.stop()
            if not self.cam.wait(10000):
                printExc("Timed out while waiting for acq thread exit!")
        if self.recordThread.isRunning():
            self.recordThread.stop()
            if not self.recordThread.wait(10000):
                raise Exception("Timed out while waiting for rec. thread exit!")
        del self.recordThread  ## Required due to cyclic reference
Esempio n. 3
0
 def run(self): ### run is called indirectly (by C somewhere) by calling start() from the parent thread; DO NOT call directly
     self.stopThread = False
     
     while True:
         try:
             with self.camLock:
                 handleCamFrames = self.newCamFrames[:]
                 self.newCamFrames = []
         except:
             debug.printExc('Error in camera recording thread:')
             break
         
         try:
             self.handleCamFrames(handleCamFrames)
             #while len(handleCamFrames) > 0:
                 #self.handleCamFrame(handleCamFrames.pop(0))
         except:
             debug.printExc('Error in camera recording thread:')
             self.toggleRecord(False)
             #self.emit(QtCore.SIGNAL('recordingFailed'))
             self.sigRecordingFailed.emit()
             
         time.sleep(10e-3)
         
         #print "  RecordThread run: stop check"
         with self.lock as l:
             #print "  RecordThread run:   got lock"
             if self.stopThread:
                 #print "  RecordThread run:   stop requested, exiting loop"
                 break
Esempio n. 4
0
    def run(self):
        try:
            with self.lock:
                videoRequested = self._video
                closeShutter = self._closeShutter
            if (videoRequested or not closeShutter) and self.laserDev is not None and self.laserDev.hasShutter:
                # force shutter to stay open for the duration of the acquisition
                self.laserDev.openShutter()

            while True:
                # take one frame
                self.acquireFrame(allowBlanking=False)

                # See whether acquisition should end
                with self.lock:
                    video, abort = self._video, self._abort
                if video is False:
                    break
                if abort is True:
                    raise Exception("Imaging acquisition aborted")
        except Exception:
            self.sigAborted.emit()
            printExc("Error in imaging acquisition thread.")
        finally:
            if videoRequested:
                self.sigVideoStopped.emit()
            if closeShutter and self.laserDev is not None and self.laserDev.hasShutter:
                self.laserDev.closeShutter()
Esempio n. 5
0
 def run(self):
     self.stopThread = False
     while self.stopThread is False:
         try:
             pos = self.dev.getPosition()
             time.sleep(self.interval)
         except:
             debug.printExc("Error in Filter Wheel poll thread:")
             time.sleep(1.0)
Esempio n. 6
0
 def setCurrentLog(self, dh):
     if dh is not None:
         try:
             self.loadFile(dh['log.txt'].name())
             self.ui.dirLabel.setText("Currently displaying " + self.currentLogDir.name(relativeTo=self.manager.baseDir)+'/log.txt')    
         except:
             debug.printExc("Error loading log file:")
             self.clear()
             self.ui.dirLabel.setText("")
     else:
         self.clear()
         self.ui.dirLabel.setText("")
Esempio n. 7
0
 def readPosition(self):
     try:
         with self.driverLock:
             pos = np.array(self.mp285.getPos())
         return pos*self.scale
     except TimeoutError:
         self.sigError.emit("Read timeout--press reset button on MP285.")
         return None
     except:
         self.sigError.emit("Read error--see console.")
         debug.printExc("Error getting packet:")
         return None
Esempio n. 8
0
 def readPosition(self):
     try:
         with self.driverLock:
             pos = np.array(self.mp285.getPos())
         return pos * self.scale
     except TimeoutError:
         self.sigError.emit("Read timeout--press reset button on MP285.")
         return None
     except:
         self.sigError.emit("Read error--see console.")
         debug.printExc("Error getting packet:")
         return None
Esempio n. 9
0
 def makeError1(self):
     ### just for testing error logging
     try:
         self.makeError2()
         # print x
     except:
         t, exc, tb = sys.exc_info()
         # logExc(message="This button doesn't work", reasons='reason a, reason b', docs='documentation')
         # if isinstance(exc, HelpfulException):
         # exc.prependErr("Button doesn't work", (t,exc,tb), reasons = ["It's supposed to raise an error for testing purposes", "You're doing it wrong."])
         # raise
         # else:
         printExc("This is the message sent to printExc.")
Esempio n. 10
0
 def makeError1(self):
     ### just for testing error logging
     try:
         self.makeError2()
         #print x
     except:
         t, exc, tb = sys.exc_info()
         #logExc(message="This button doesn't work", reasons='reason a, reason b', docs='documentation')
         #if isinstance(exc, HelpfulException):
         #exc.prependErr("Button doesn't work", (t,exc,tb), reasons = ["It's supposed to raise an error for testing purposes", "You're doing it wrong."])
         #raise
         #else:
         printExc("This is the message sent to printExc.")
Esempio n. 11
0
 def startAcquireClicked(self, mode):
     """User clicked the acquire video button.
     """
     try:
         self.cam.setParam('triggerMode', 'Normal', autoRestart=False)
         self.setBinning(autoRestart=False)
         self.setExposure(autoRestart=False)
         self.updateRegion(autoRestart=False)
         self.cam.start()
         Manager.logMsg("Camera started aquisition.", importance=0)
     except:
         self.imagingCtrl.acquisitionStopped()
         printExc("Error starting camera:")
Esempio n. 12
0
 def setCurrentLog(self, dh):
     if dh is not None:
         try:
             self.loadFile(dh['log.txt'].name())
             self.ui.dirLabel.setText("Currently displaying " +
                                      self.currentLogDir.name(
                                          relativeTo=self.manager.baseDir) +
                                      '/log.txt')
         except:
             debug.printExc("Error loading log file:")
             self.clear()
             self.ui.dirLabel.setText("")
     else:
         self.clear()
         self.ui.dirLabel.setText("")
Esempio n. 13
0
def listFileTypes():
    """Return a list of the names of all available fileType subclasses."""
    global KNOWN_FILE_TYPES
    if KNOWN_FILE_TYPES is None:
        KNOWN_FILE_TYPES = {}
        files = os.listdir(os.path.dirname(__file__))
        for f in ['filetypes.py', '__init__.py', 'FileType.py']:
            if f in files:
                files.remove(f)
        typs = [os.path.splitext(f)[0] for f in files if f[-3:] == '.py']
        for typ in typs:
            try:
                getFileType(typ)
            except:
                debug.printExc("Error loading file type library '%s':" % typ)
    return KNOWN_FILE_TYPES.keys()
Esempio n. 14
0
def listFileTypes():
    """Return a list of the names of all available fileType subclasses."""
    global KNOWN_FILE_TYPES
    if KNOWN_FILE_TYPES is None:
        KNOWN_FILE_TYPES = {}
        files = os.listdir(os.path.dirname(__file__))
        for f in ['filetypes.py', '__init__.py', 'FileType.py']:
            if f in files:
                files.remove(f)
        typs = [os.path.splitext(f)[0] for f in files if f[-3:] == '.py']
        for typ in typs:
            try:
                getFileType(typ)
            except:
                debug.printExc("Error loading file type library '%s':" % typ)
    return KNOWN_FILE_TYPES.keys()
Esempio n. 15
0
    def loadFileRequested(self, fhList):
        canvas = self.getElement('Canvas')
        model = self.dataModel

        for fh in fhList:
            try:
                ## TODO: use more clever detection of Scan data here.
                if fh.isFile() or model.dirType(fh) == 'Cell':
                    canvas.addFile(fh)
                else:
                    #self.loadScan(fh)
                    debug.printExc("MapAnalyzer does not yet support loading scans")
                    return False
                return True
            except:
                debug.printExc("Error loading file %s" % fh.name())
                return False
Esempio n. 16
0
 def toggleAcquire(self):
     if self.ui.acquireVideoBtn.isChecked():
         try:
             self.cam.setParam('triggerMode', 'Normal', autoRestart=False)
             self.setBinning(autoRestart=False)
             self.setExposure(autoRestart=False)
             self.updateRegion(autoRestart=False)
             self.cam.start()
             Manager.logMsg("Camera started aquisition.", importance=0)
         except:
             self.ui.acquireVideoBtn.setChecked(False)
             printExc("Error starting camera:")
     
     else:
         #print "ACQ untoggled, stop record"
         self.toggleRecord(False)
         self.cam.stop()
         Manager.logMsg("Camera stopped acquisition.", importance=0)
Esempio n. 17
0
 def run(self):
     # run is invoked in the worker thread automatically after calling start()
     self.stopThread = False
     
     while True:
         with self.lock:
             if self.stopThread:
                 break
             newFrames = self.newFrames[:]
             self.newFrames = []
         
         try:
             self.handleFrames(newFrames)
         except:
             debug.printExc('Error in image recording thread:')
             self.sigRecordingFailed.emit()
             
         time.sleep(100e-3)
Esempio n. 18
0
    def loadFileRequested(self, fhList):
        canvas = self.getElement('Canvas')
        model = self.dataModel

        with pg.ProgressDialog("Loading data..", 0, len(fhList)) as dlg:
            for fh in fhList:
                try:
                    ## TODO: use more clever detection of Scan data here.
                    if fh.isFile() or model.dirType(fh) == 'Cell':
                        canvas.addFile(fh)
                    else:
                        self.loadScan(fh)
                    return True
                except:
                    debug.printExc("Error loading file %s" % fh.name())
                    return False
                dlg += 1
                if dlg.wasCanceled():
                    return
Esempio n. 19
0
    def quit(self):
        self.imagingCtrl.quit()

        if self.hasQuit:
            return

        try:
            self.cam.sigNewFrame.disconnect(self.newFrame)
            self.cam.sigCameraStopped.disconnect(self.cameraStopped)
            self.cam.sigCameraStarted.disconnect(self.cameraStarted)
            self.cam.sigShowMessage.disconnect(self.showMessage)
        except TypeError:
            pass

        self.hasQuit = True
        if self.cam.isRunning():
            self.cam.stop()
            if not self.cam.wait(10000):
                printExc("Timed out while waiting for acq thread exit!")
Esempio n. 20
0
    def loadFileRequested(self, fhList):
        canvas = self.getElement('Canvas')
        model = self.dataModel

        with pg.ProgressDialog("Loading data..", 0, len(fhList)) as dlg:
            for fh in fhList:
                try:
                    ## TODO: use more clever detection of Scan data here.
                    if fh.isFile() or model.dirType(fh) == 'Cell':
                        canvas.addFile(fh)
                    else:
                        self.loadScan(fh)
                    return True
                except:
                    debug.printExc("Error loading file %s" % fh.name())
                    return False
                dlg += 1
                if dlg.wasCancelled():
                    return
Esempio n. 21
0
    def __init__(self, host, flowchartDir=None, dbIdentity="EventDetector", dbCtrl=None):
        AnalysisModule.__init__(self, host)
        
        if flowchartDir is None:
            flowchartDir = os.path.join(os.path.abspath(os.path.split(__file__)[0]), "flowcharts")
        self.flowchart = Flowchart(filePath=flowchartDir)
        self.dbIdentity = dbIdentity  ## how we identify to the database; this determines which tables we own
        #self.loader = FileLoader.FileLoader(host.dataManager())
        #self.setCentralWidget(self.flowchart.widget())
        #self.ui.chartDock1.setWidget(self.flowchart.widget())
        self.flowchart.addInput("dataIn")
        self.flowchart.addOutput('events')
        #self.flowchart.addOutput('regions', multi=True)
        self.flowchart.sigChartLoaded.connect(self.connectPlots)
        
        if dbCtrl == None:
            self.dbCtrl = DBCtrl(self, identity=self.dbIdentity)
            self.dbCtrl.storeBtn.clicked.connect(self.storeClicked)
        else:
            self.dbCtrl = dbCtrl(self, identity=self.dbIdentity)

        #self.ctrl = QtGui.QLabel('LABEL')
        self.ctrl = self.flowchart.widget()
        self._elements_ = OrderedDict([
            ('File Loader', {'type': 'fileInput', 'size': (200, 300), 'host': self}),
            ('Database', {'type': 'ctrl', 'object': self.dbCtrl, 'size': (200,300), 'pos': ('bottom', 'File Loader')}),
            ('Data Plot', {'type': 'plot', 'pos': ('right',), 'size': (800, 300)}),
            ('Detection Opts', {'type': 'ctrl', 'object': self.ctrl, 'pos': ('bottom', 'Database'), 'size': (200, 500)}),
            ('Filter Plot', {'type': 'plot', 'pos': ('bottom', 'Data Plot'), 'size': (800, 300)}),
            ('Output Table', {'type': 'table', 'pos': ('bottom', 'Filter Plot'), 'optional': True, 'size': (800,200)}),
        ])
        
        self.initializeElements()
        
        try:
            ## load default chart
            self.flowchart.loadFile(os.path.join(flowchartDir, 'default.fc'))
        except:
            debug.printExc('Error loading default flowchart:')
        
        self.flowchart.sigOutputChanged.connect(self.outputChanged)
Esempio n. 22
0
    def run(self):
        self.stopThread = False
        with self.driverLock:
            self.fwPosChanged.emit(self.driver.getPos())
        while True:
            try:
                with self.driverLock:
                    pos = self.driver.getPos()
                self.fwPosChanged.emit(pos)
                time.sleep(0.5)
            except:
                debug.printExc("Error in Filter Wheel communication thread:")

            self.lock.lock()
            if self.stopThread:
                self.lock.unlock()
                break
            self.lock.unlock()
            time.sleep(0.02)

        self.driver.close()
Esempio n. 23
0
    def __init__(self, dm, config, name):

        # Generate config to use for DAQ
        self.devLock = Mutex(Mutex.Recursive)

        daqConfig = {
            'command': config['Command'],
            'primary': config['ScaledSignal'],
        }

        self.holding = {
            'vc': config.get('vcHolding', -0.05),
            'ic': config.get('icHolding', 0.0)
        }

        self.mode = 'i=0'

        self.config = config

        DAQGeneric.__init__(self, dm, daqConfig, name)

        try:
            self.setHolding()
        except:
            printExc("Error while setting holding value:")

        # Start a remote process to run the simulation.
        self.process = mp.Process()
        rsys = self.process._import('sys')
        rsys._setProxyOptions(
            returnType='proxy'
        )  # need to access remote path by proxy, not by value
        rsys.path.append(os.path.abspath(os.path.dirname(__file__)))
        if config['simulator'] == 'builtin':
            self.simulator = self.process._import('hhSim')
        elif config['simulator'] == 'neuron':
            self.simulator = self.process._import('neuronSim')

        dm.declareInterface(name, ['clamp'], self)
Esempio n. 24
0
    def __init__(self, dm, config, name):

        # Generate config to use for DAQ 
        daqConfig = {}
        self.devLock = Mutex(Mutex.Recursive)
        
        daqConfig = {
            'command': config['Command'],
            'primary': config['ScaledSignal'],
        }
            
        self.holding = {
            'vc': config.get('vcHolding', -0.05),
            'ic': config.get('icHolding', 0.0)
        }
        
        self.mode = 'i=0'
        
        self.config = config
        
        DAQGeneric.__init__(self, dm, daqConfig, name)
        
        try:
            self.setHolding()
        except:
            printExc("Error while setting holding value:")
            
        # Start a remote process to run the simulation.
        self.process = mp.Process()
        rsys = self.process._import('sys')
        rsys._setProxyOptions(returnType='proxy') # need to access remote path by proxy, not by value
        rsys.path.append(os.path.abspath(os.path.dirname(__file__)))
        if config['simulator'] == 'builtin':
            self.simulator = self.process._import('hhSim')
        elif config['simulator'] == 'neuron':
            self.simulator = self.process._import('neuronSima')
        
        dm.declareInterface(name, ['clamp'], self)
Esempio n. 25
0
def suggestWriteType(data, fileName=None):
    """Guess which fileType class should be used to write data.
    If fileName is specified, this may influence the guess.
    Return the name of the class."""
    maxVal = None
    maxType = None
    #print "Suggest for type %s, name %s" % (type(data), str(fileName))
    for typ in listFileTypes():
        try:
            cls = getFileType(typ)
        except:
            debug.printExc("ignoring filetype %s" % typ)
            continue
        priority = cls.acceptsData(data, fileName)
        #print "filetype %s has priority %d" %(typ, int(priority))
        if priority is False:
            continue
        else:
            if maxVal is None or priority > maxVal:
                maxVal = priority
                maxType = typ
    #print "Suggesting", maxType
    return maxType
Esempio n. 26
0
    def run(self):
        self.stopThread = False
        with self.driverLock:
            self.sigWavelengthChanged.emit(self.driver.getWavelength() * 1e-9)
        while True:
            try:
                with self.driverLock:
                    power = self.driver.getPower() * 1e-3
                    wl = self.driver.getWavelength() * 1e-9
                self.sigPowerChanged.emit(power)
                self.sigWavelengthChanged.emit(wl)
                time.sleep(0.5)
            except:
                debug.printExc("Error in Coherent laser communication thread:")

            self.lock.lock()
            if self.stopThread:
                self.lock.unlock()
                break
            self.lock.unlock()
            time.sleep(0.02)

        self.driver.close()
Esempio n. 27
0
def suggestWriteType(data, fileName=None):
    """Guess which fileType class should be used to write data.
    If fileName is specified, this may influence the guess.
    Return the name of the class."""
    maxVal = None
    maxType = None
    #print "Suggest for type %s, name %s" % (type(data), str(fileName))
    for typ in listFileTypes():
        try:
            cls = getFileType(typ)
        except:
            debug.printExc("ignoring filetype %s" % typ)
            continue
        priority = cls.acceptsData(data, fileName)
        #print "filetype %s has priority %d" %(typ, int(priority))
        if priority is False:
            continue
        else:
            if maxVal is None or priority > maxVal:
                maxVal = priority
                maxType = typ
    #print "Suggesting", maxType
    return maxType
Esempio n. 28
0
 def __init__(self, host, flowchartDir=None):
     AnalysisModule.__init__(self, host)
     
     self.dbIdentity = "IVCurveAnalyzer"  ## how we identify to the database; this determines which tables we own
     
     if flowchartDir is None:
         flowchartDir = os.path.join(os.path.abspath(os.path.split(__file__)[0]), "flowcharts")
     self.flowchart = Flowchart(filePath=flowchartDir)
     
     self.flowchart.addInput("dataIn")
     #self.flowchart.addOutput('events')
     self.flowchart.addOutput('regions', multi=True)        
     #self.flowchart.sigChartLoaded.connect(self.connectPlots)
     
     
     ### DBCtrl class is from EventDetector -- need to make my own here
     #self.dbCtrl = DBCtrl(self, identity=self.dbIdentity)
     #self.dbCtrl.storeBtn.clicked.connect(self.storeClicked)
     
     self.ctrl = self.flowchart.widget()
     self._elements_ = OrderedDict([
         ('File Loader', {'type': 'fileInput', 'size': (200, 300), 'host': self}),
         #('Database', {'type': 'ctrl', 'object': self.dbCtrl, 'size': (200,300), 'pos': ('bottom', 'File Loader')}),
         ('Data Plot', {'type': 'plot', 'pos': ('right',), 'size': (800, 300)}),
         ('Detection Opts', {'type': 'ctrl', 'object': self.ctrl, 'pos': ('bottom', 'File Loader'), 'size': (200, 500)}),
         ('IV Plot', {'type': 'plot', 'pos': ('bottom', 'Data Plot'), 'size': (400, 300)}),
         ('Output Table', {'type': 'table', 'pos': ('bottom', 'IV Plot'), 'optional': True, 'size': (800,200)}),
         ('FI Plot', {'type': 'plot', 'pos': ('right', 'IV Plot'), 'size': (400, 300)}),
     ])
     
     self.initializeElements()
     
     try:
         ## load default chart
         self.flowchart.loadFile(os.path.join(flowchartDir, 'default.fc'))
     except:
         debug.printExc('Error loading default flowchart:')
Esempio n. 29
0
    def run(self):
        self.stopThread = False
        with self.driverLock:
            self.sigWavelengthChanged.emit(self.driver.getWavelength()*1e-9)
        while True:
            try:
                with self.driverLock:
                    power = self.driver.getPower() * 1e-3
                    wl = self.driver.getWavelength()*1e-9
                self.sigPowerChanged.emit(power)
                self.sigWavelengthChanged.emit(wl)
                time.sleep(0.5)
            except:
                debug.printExc("Error in Coherent laser communication thread:")
                
            self.lock.lock()
            if self.stopThread:
                self.lock.unlock()
                break
            self.lock.unlock()
            time.sleep(0.02)


        self.driver.close()
Esempio n. 30
0
    def __init__(self, dm, config, name):
		
        # Generate config to use for DAQ 
        daqConfig = {}
        
        for ch in ['GainChannel', 'LPFChannel', 'ModeChannel']:
            if ch not in config:
                continue
            daqConfig[ch]  = config[ch].copy()
        #if 'GainChannel' in config:
        #    daqConfig['gain'] = {'type': 'ai', 'channel': config['GainChannel']}
        #if 'LPFChannel' in config:
        #    daqConfig['LPF'] = {'type': 'ai', 'channel': config['LPFChannel'], 'units': 'Hz'}
        if 'ScaledSignal' in config:
            #daqConfig['primary'] = {'type': 'ai', 'channel': config['ScaledSignal']}
            daqConfig['primary'] = config['ScaledSignal']
            if config['ScaledSignal'].get('type', None) != 'ai':
                raise Exception("AxoPatch200: ScaledSignal configuration must have type:'ai'")
        if 'Command' in config:
            #daqConfig['command'] = {'type': 'ao', 'channel': config['Command']}
            daqConfig['command'] = config['Command']
            if config['Command'].get('type', None) != 'ao':
                raise Exception("AxoPatch200: ScaledSignal configuration must have type:'ao'")
            
        ## Note that both of these channels can be present, but we will only ever record from one at a time.
        ## Usually, we'll record from "I OUTPUT" in current clamp and "10 Vm OUTPUT" in voltage clamp.
        if 'SecondaryVCSignal' in config: 
            self.hasSecondaryChannel = True
            #daqConfig['secondary'] = {'type': 'ai', 'channel': config['SecondaryVCSignal']}
            daqConfig['secondary'] = config['SecondaryVCSignal']
            if config['SecondaryVCSignal'].get('type', None) != 'ai':
                raise Exception("AxoPatch200: SecondaryVCSignal configuration must have type:'ai'")
        elif 'SecondaryICSignal' in config:
            self.hasSecondaryChannel = True
            #daqConfig['secondary'] = {'type': 'ai', 'channel': config['SecondaryICSignal']}
            daqConfig['secondary'] = config['SecondaryICSignal']
            if config['SecondaryICSignal'].get('type', None) != 'ai':
                raise Exception("AxoPatch200: SecondaryICSignal configuration must have type:'ai'")
        else:
            self.hasSecondaryChannel = False
        
        self.version = config.get('version', '200B')

        # Axopatch gain telegraph
        # telegraph should not read below 2 V in CC mode
        self.gain_tel = np.array([0.5,  1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5])
        self.gain_vm  = np.array([0.5,  0.5, 0.5, 0.5, 1,   2,   5,   10,  20,  50,  100, 200, 500]) * 1e9  ## values in mv/pA
        self.gain_im  = np.array([0.05, 0.1, 0.2, 0.5, 1,   2,   5,   10,  20,  50,  100, 200, 500])        ## values in mV/mV

        # Axopatch Lowpass Bessel Filter
        self.lpf_tel = np.array([2.0, 4.0, 6.0, 8.0, 10.0])
        self.lpf_freq = np.array([1.0, 2.0, 5.0, 10.0, 50.0])

        if self.version == '200':
            # telegraph voltage/output translation from the Axopatch 200 amplifier
            self.mode_tel = np.array([6, 4, 2])
            self.modeNames = OrderedDict([(0, 'V-Clamp'), (1, 'Track'), (2, 'I-Clamp')])
            self.ivModes = {'V-Clamp':'vc', 'Track':'ic', 'I-Clamp':'ic', 'vc':'vc', 'ic':'ic'}
            self.modeAliases = {'ic': 'I-Clamp', 'i=0': 'Track', 'vc': 'V-Clamp'}

        elif self.version == '200A':
            # telegraph voltage/output translation from the Axopatch 200 amplifier
            self.mode_tel = np.array([6, 4, 2, 1])
            self.modeNames = OrderedDict([(0, 'V-Clamp'), (1, 'Track'), (2, 'I-Clamp Normal'), (3, 'I-Clamp Fast'),  ])
            self.ivModes = {'V-Clamp':'vc', 'Track':'vc', 'I-Clamp Fast':'ic', 'I-Clamp Normal':'ic', 'vc':'vc', 'ic':'ic'}
            self.modeAliases = {'ic': 'I-Clamp Fast', 'i=0': 'Track', 'vc': 'V-Clamp'}

        elif self.version == '200B':
            # telegraph voltage/output translation from the Axopatch 200 amplifier
            self.mode_tel = np.array([6, 4, 3, 2, 1])
            self.modeNames = OrderedDict([(0, 'V-Clamp'), (2, 'I=0'), (4, 'I-Clamp Fast'), (3, 'I-Clamp Normal'), (1, 'Track'), ])
            self.ivModes = {'V-Clamp':'vc', 'Track':'vc', 'I=0':'ic', 'I-Clamp Fast':'ic', 'I-Clamp Normal':'ic', 'vc':'vc', 'ic':'ic'}
            self.modeAliases = {'ic': 'I-Clamp Fast', 'i=0': 'I=0', 'vc': 'V-Clamp'}
            self.lpf_freq[-1] = 100.0  # 200B's highest LPF value is 100kHz instead of 50.
        else:
            raise Exception("AxoPatch200: version must be '200', '200A' or '200B' (got %r)" % version)

        self.holding = {
            'vc': config.get('vcHolding', -0.05),
            'ic': config.get('icHolding', 0.0)
        }
        
        self.config = config
        self.modeLock = Mutex(Mutex.Recursive)   ## protects self.mdCanceled
        self.devLock = Mutex(Mutex.Recursive)    ## protects self.holding, possibly self.config, ..others, perhaps?
        self.mdCanceled = False
        
        DAQGeneric.__init__(self, dm, daqConfig, name)
        
        self.modeDialog = QtGui.QMessageBox()
        self.modeDialog.hide()
        self.modeDialog.setModal(False)
        self.modeDialog.setWindowTitle("Mode Switch Request")
        self.modeDialog.addButton(self.modeDialog.Cancel)
        self.modeDialog.buttonClicked.connect(self.modeDialogClicked)
        
        self.sigShowModeDialog.connect(self.showModeDialog)
        self.sigHideModeDialog.connect(self.hideModeDialog)
        
        
        
        try:
            self.setHolding()
        except:
            printExc("Error while setting holding value:")
            
        dm.declareInterface(name, ['clamp'], self)
Esempio n. 31
0
    def drawFrame(self):
        if self.hasQuit:
            return
        #sys.stdout.write('+')
        try:

            ## If we last drew a frame < 1/30s ago, return.
            t = pg.ptime.time()
            if (self.lastDrawTime
                    is not None) and (t - self.lastDrawTime < .03):
                #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 = pg.debug.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.displayFps = 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.getImage()
            info = self.currentFrame.info()
            prof()

            ## divide the background out of the current frame if needed
            data = self.bgCtrl.processImage(data)
            prof()

            ## Set new levels if auto gain is enabled
            self.contrastCtrl.processImage(data)
            prof()

            ## update image in viewport
            self._imageItem.updateImage(
                data.copy())  # using data.copy() here avoids crashes!
            prof()

            self.imageUpdated.emit(self.currentFrame)
            prof()

            prof.finish()

        except:
            printExc('Error while drawing new frames:')
        finally:
            pass
Esempio n. 32
0
    def __init__(self,
                 host,
                 flowchartDir=None,
                 dbIdentity="EventDetector",
                 dbCtrl=None):
        AnalysisModule.__init__(self, host)

        if flowchartDir is None:
            flowchartDir = os.path.join(
                os.path.abspath(os.path.split(__file__)[0]), "flowcharts")
        self.flowchart = Flowchart(filePath=flowchartDir)
        self.dbIdentity = dbIdentity  ## how we identify to the database; this determines which tables we own
        #self.loader = FileLoader.FileLoader(host.dataManager())
        #self.setCentralWidget(self.flowchart.widget())
        #self.ui.chartDock1.setWidget(self.flowchart.widget())
        self.flowchart.addInput("dataIn")
        self.flowchart.addOutput('events')
        #self.flowchart.addOutput('regions', multi=True)
        self.flowchart.sigChartLoaded.connect(self.connectPlots)

        if dbCtrl == None:
            self.dbCtrl = DBCtrl(self, identity=self.dbIdentity)
            self.dbCtrl.storeBtn.clicked.connect(self.storeClicked)
        else:
            self.dbCtrl = dbCtrl(self, identity=self.dbIdentity)

        #self.ctrl = QtGui.QLabel('LABEL')
        self.ctrl = self.flowchart.widget()
        self._elements_ = OrderedDict([
            ('File Loader', {
                'type': 'fileInput',
                'size': (200, 300),
                'host': self
            }),
            ('Database', {
                'type': 'ctrl',
                'object': self.dbCtrl,
                'size': (200, 300),
                'pos': ('bottom', 'File Loader')
            }),
            ('Data Plot', {
                'type': 'plot',
                'pos': ('right', ),
                'size': (800, 300)
            }),
            ('Detection Opts', {
                'type': 'ctrl',
                'object': self.ctrl,
                'pos': ('bottom', 'Database'),
                'size': (200, 500)
            }),
            ('Filter Plot', {
                'type': 'plot',
                'pos': ('bottom', 'Data Plot'),
                'size': (800, 300)
            }),
            ('Output Table', {
                'type': 'table',
                'pos': ('bottom', 'Filter Plot'),
                'optional': True,
                'size': (800, 200)
            }),
        ])

        self.initializeElements()

        try:
            ## load default chart
            self.flowchart.loadFile(os.path.join(flowchartDir, 'default.fc'))
        except:
            debug.printExc('Error loading default flowchart:')

        self.flowchart.sigOutputChanged.connect(self.outputChanged)
Esempio n. 33
0
    def run(self):
        self.stopThread = False
        #self.sp = serial.Serial(int(self.port), baudrate=self.baud, bytesize=serial.EIGHTBITS)
        #time.sleep(3) ## Wait a few seconds for the mouse to say hello
        ## clear buffer before starting
        #if self.sp.inWaiting() > 0:
        #print "Discarding %d bytes" % self.sp.inWaiting()
        #self.sp.read(self.sp.inWaiting())
        #import wingdbstub
        print "  Starting MP285 thread: 0x%x" % int(
            QtCore.QThread.currentThreadId())
        #import sip
        #print "    also known as 0x%x" % sip.unwrapinstance(self)
        velocity = np.array([0, 0, 0])
        pos = [0, 0, 0]

        try:
            self.getImmediatePos()
            monitor = True
        except:
            debug.printExc("Sutter MP285: Cannot determine position:")
            monitor = False

        while True:
            try:
                ## Lock and copy state to local variables
                with self.lock:
                    update = self.update
                    self.update = False
                    limits = deepcopy(self.limits)
                    maxSpeed = self.maxSpeed
                    newVelocity = np.array(self.velocity[:])
                    resolution = self.resolution
                    limitChanged = self.limitChanged
                    self.limitChanged = False

                ## if limits have changed, inform the device
                if monitor and limitChanged:  ## monitor is only true if this is a customized device with limit checking
                    self.sendLimits()

                ## If requested velocity is different from the current velocity, handle that.
                if np.any(newVelocity != velocity):
                    speed = np.clip(np.sum(newVelocity**2)**0.5, 0.,
                                    1.)  ## should always be 0.0-1.0
                    #print "new velocity:", newVelocity, "speed:", speed

                    if speed == 0:
                        nv = np.array([0, 0, 0])
                    else:
                        nv = newVelocity / speed

                    speed = np.clip(speed, 0, maxSpeed)
                    #print "final speed:", speed

                    ## stop current move, get position, start new move
                    #print "stop.."
                    self.stopMove()
                    #print "stop done."

                    #print "getpos..."
                    pos1 = self.readPosition()
                    if pos1 is not None:

                        if speed > 0:
                            #print "   set new velocity"
                            self.writeVelocity(speed,
                                               nv,
                                               limits=limits,
                                               pos=pos1,
                                               resolution=resolution)
                            #print "   done"

                        ## report current position

                        velocity = newVelocity
                    #print "done"

                ## If velocity is 0, we can do some position checks
                if np.all(velocity == 0):
                    newPos = None
                    if update:
                        newPos = self.readPosition()
                    elif monitor:
                        newPos = self.getImmediatePos()

                    if newPos is not None:  ## If position has changed, emit a signal.

                        change = [
                            newPos[i] - pos[i] for i in range(len(newPos))
                        ]
                        pos = newPos

                        if any(change):
                            #self.emit(QtCore.SIGNAL('positionChanged'), {'rel': change, 'abs': self.pos})
                            self.sigPositionChanged.emit({
                                'rel': change,
                                'abs': pos
                            })
                else:
                    ## moving; make a guess about the current position
                    pass
            except:
                pass
                debug.printExc("Error in MP285 thread:")

            self.lock.lock()
            if self.stopThread:
                self.lock.unlock()
                break
            self.lock.unlock()
            time.sleep(0.02)

        self.mp285.close()
Esempio n. 34
0
    def __init__(self, host, flowchartDir=None):
        AnalysisModule.__init__(self, host)

        self.dbIdentity = "IVCurveAnalyzer"  ## how we identify to the database; this determines which tables we own

        if flowchartDir is None:
            flowchartDir = os.path.join(
                os.path.abspath(os.path.split(__file__)[0]), "flowcharts")
        self.flowchart = Flowchart(filePath=flowchartDir)

        self.flowchart.addInput("dataIn")
        #self.flowchart.addOutput('events')
        self.flowchart.addOutput('regions', multi=True)
        #self.flowchart.sigChartLoaded.connect(self.connectPlots)

        ### DBCtrl class is from EventDetector -- need to make my own here
        #self.dbCtrl = DBCtrl(self, identity=self.dbIdentity)
        #self.dbCtrl.storeBtn.clicked.connect(self.storeClicked)

        self.ctrl = self.flowchart.widget()
        self._elements_ = OrderedDict([
            ('File Loader', {
                'type': 'fileInput',
                'size': (200, 300),
                'host': self
            }),
            #('Database', {'type': 'ctrl', 'object': self.dbCtrl, 'size': (200,300), 'pos': ('bottom', 'File Loader')}),
            ('Data Plot', {
                'type': 'plot',
                'pos': ('right', ),
                'size': (800, 300)
            }),
            ('Detection Opts', {
                'type': 'ctrl',
                'object': self.ctrl,
                'pos': ('bottom', 'File Loader'),
                'size': (200, 500)
            }),
            ('IV Plot', {
                'type': 'plot',
                'pos': ('bottom', 'Data Plot'),
                'size': (400, 300)
            }),
            ('Output Table', {
                'type': 'table',
                'pos': ('bottom', 'IV Plot'),
                'optional': True,
                'size': (800, 200)
            }),
            ('FI Plot', {
                'type': 'plot',
                'pos': ('right', 'IV Plot'),
                'size': (400, 300)
            }),
        ])

        self.initializeElements()

        try:
            ## load default chart
            self.flowchart.loadFile(os.path.join(flowchartDir, 'default.fc'))
        except:
            debug.printExc('Error loading default flowchart:')
Esempio n. 35
0
    def __init__(self, image=None, **opts):

        ## If no image was specified, check for a file handle..
        if image is None:
            image = opts.get('handle', None)

        item = None
        self.data = None

        if isinstance(image, QtGui.QGraphicsItem):
            item = image
        elif isinstance(image, np.ndarray):
            self.data = image
        elif isinstance(image, DataManager.FileHandle):
            opts['handle'] = image
            self.handle = image
            self.data = self.handle.read()

            if 'name' not in opts:
                opts['name'] = self.handle.shortName()

            try:
                if 'transform' in self.handle.info():
                    tr = pg.SRTTransform3D(self.handle.info()['transform'])
                    tr = pg.SRTTransform(tr)  ## convert to 2D
                    opts['pos'] = tr.getTranslation()
                    opts['scale'] = tr.getScale()
                    opts['angle'] = tr.getRotation()
                else:  ## check for older info formats
                    if 'imagePosition' in self.handle.info():
                        opts['scale'] = self.handle.info()['pixelSize']
                        opts['pos'] = self.handle.info()['imagePosition']
                    elif 'Downsample' in self.handle.info():
                        ### Needed to support an older format stored by 2p imager
                        if 'pixelSize' in self.handle.info():
                            opts['scale'] = self.handle.info()['pixelSize']
                        if 'microscope' in self.handle.info():
                            m = self.handle.info()['microscope']
                            opts['pos'] = m['position'][0:2]
                        else:
                            info = self.data._info[-1]
                            opts['pos'] = info.get('imagePosition', None)
                    elif hasattr(self.data, '_info'):
                        info = self.data._info[-1]
                        opts['scale'] = info.get('pixelSize', None)
                        opts['pos'] = info.get('imagePosition', None)
                    else:
                        opts['defaultUserTransform'] = {'scale': (1e-5, 1e-5)}
                        opts['scalable'] = True
            except:
                debug.printExc(
                    'Error reading transformation for image file %s:' %
                    image.name())

        if item is None:
            item = pg.ImageItem()
        CanvasItem.__init__(self, item, **opts)

        self.splitter = QtGui.QSplitter()
        self.splitter.setOrientation(QtCore.Qt.Vertical)
        self.layout.addWidget(self.splitter, self.layout.rowCount(), 0, 1, 2)

        self.filterGroup = pg.GroupBox("Image Filter")
        fgl = QtGui.QGridLayout()
        fgl.setContentsMargins(3, 3, 3, 3)
        fgl.setSpacing(1)
        self.filterGroup.setLayout(fgl)
        self.filter = ImageFilterWidget()
        self.filter.sigStateChanged.connect(self.filterStateChanged)
        fgl.addWidget(self.filter)
        self.splitter.addWidget(self.filterGroup)

        self.histogram = pg.HistogramLUTWidget()
        self.histogram.setImageItem(self.graphicsItem())

        # addWidget arguments: row, column, rowspan, colspan
        self.splitter.addWidget(self.histogram)

        self.imgModeCombo = QtGui.QComboBox()
        self.imgModeCombo.addItems(
            ['SourceOver', 'Overlay', 'Plus', 'Multiply'])
        self.layout.addWidget(self.imgModeCombo, self.layout.rowCount(), 0, 1,
                              1)
        self.imgModeCombo.currentIndexChanged.connect(self.imgModeChanged)

        self.autoBtn = QtGui.QPushButton("Auto")
        self.autoBtn.setCheckable(True)
        self.autoBtn.setChecked(True)
        self.layout.addWidget(self.autoBtn,
                              self.layout.rowCount() - 1, 1, 1, 1)

        self.timeSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
        self.layout.addWidget(self.timeSlider, self.layout.rowCount(), 0, 1, 2)
        self.timeSlider.valueChanged.connect(self.timeChanged)

        # ## controls that only appear if there is a time axis
        self.timeControls = [self.timeSlider]

        if self.data is not None:
            if isinstance(self.data, pg.metaarray.MetaArray):
                self.filter.setInput(self.data.asarray())
            else:
                self.filter.setInput(self.data)
            self.updateImage()

            # Needed to ensure selection box wraps the image properly
            tr = self.saveTransform()
            self.resetUserTransform()
            self.restoreTransform(tr)
Esempio n. 36
0
 def recordThreadStopped(self):
     self.endStack()
     self.ui.recordStackBtn.setEnabled(
         False)  ## Recording thread has stopped, can't record anymore.
     printExc("Recording thread died! See console for error message.")
Esempio n. 37
0
    def __init__(self, host):
        AnalysisModule.__init__(self, host)
        if self.dataModel is None:
            raise Exception("Photostim analysis module requires a data model, but none is loaded yet.")
        self.dbIdentity = "Photostim"  ## how we identify to the database; this determines which tables we own
        self.selectedSpot = None
        
        ## setup analysis flowchart
        modPath = os.path.abspath(os.path.split(__file__)[0])
        flowchartDir = os.path.join(modPath, "analysis_fc")
        self.flowchart = Flowchart(filePath=flowchartDir)
        self.flowchart.addInput('events')
        self.flowchart.addInput('regions')
        self.flowchart.addInput('fileHandle')
        self.flowchart.addOutput('dataOut')
        self.analysisCtrl = self.flowchart.widget()
        
        ## color mapper
        self.mapper = ColorMapper.ColorMapper(filePath=os.path.join(modPath, "colormaps"))
        self.mapCtrl = QtGui.QWidget()
        self.mapLayout = QtGui.QVBoxLayout()
        self.mapCtrl.setLayout(self.mapLayout)
        self.mapLayout.splitter = QtGui.QSplitter()
        self.mapLayout.splitter.setOrientation(QtCore.Qt.Vertical)
        self.mapLayout.splitter.setContentsMargins(0,0,0,0)
        self.mapLayout.addWidget(self.mapLayout.splitter)
        self.mapLayout.splitter.addWidget(self.analysisCtrl)
        #self.mapLayout.splitter.addWidget(QtGui.QSplitter())
        self.mapLayout.splitter.addWidget(self.mapper)
        #self.mapLayout.splitter.addWidget(self.recolorBtn)
        
        self.recolorLayout = QtGui.QHBoxLayout()
        self.recolorWidget = QtGui.QWidget()
        self.mapLayout.splitter.addWidget(self.recolorWidget)
        self.recolorWidget.setLayout(self.recolorLayout)
        self.recolorBtn = QtGui.QPushButton('Recolor')
        self.recolorLayout.addWidget(self.recolorBtn)
        self.recolorParallelCheck = QtGui.QCheckBox('Parallel')
        self.recolorParallelCheck.setChecked(True)
        self.recolorLayout.addWidget(self.recolorParallelCheck)
        
        ## scatter plot
        self.scatterPlot = ScatterPlotter()
        self.scatterPlot.sigClicked.connect(self.scatterPlotClicked)
        
        ## setup map DB ctrl
        self.dbCtrl = DBCtrl(self, self.dbIdentity)
        
        ## storage for map data
        #self.scanItems = {}
        self.scans = []
        #self.seriesScans = {}
        self.maps = []
        
        ## create event detector
        fcDir = os.path.join(os.path.abspath(os.path.split(__file__)[0]), "detector_fc")
        self.detector = EventDetector.EventDetector(host, flowchartDir=fcDir, dbIdentity=self.dbIdentity+'.events')
        
        ## override some of its elements
        self.detector.setElement('File Loader', self)
        self.detector.setElement('Database', self.dbCtrl)
        
            
        ## Create element list, importing some gui elements from event detector
        elems = self.detector.listElements()
        self._elements_ = OrderedDict([
            ('Database', {'type': 'ctrl', 'object': self.dbCtrl, 'size': (300, 600)}),
            ('Scatter Plot', {'type': 'ctrl', 'object': self.scatterPlot, 'pos': ('right',), 'size': (700,400)}),
            ('Canvas', {'type': 'canvas', 'pos': ('above', 'Scatter Plot'), 'size': (700,400), 'allowTransforms': False, 'hideCtrl': True, 'args': {'name': 'Photostim'}}),
            #('Maps', {'type': 'ctrl', 'pos': ('bottom', 'Database'), 'size': (200,200), 'object': self.mapDBCtrl}),
            ('Map Opts', {'type': 'ctrl', 'object': self.mapCtrl, 'pos': ('above', 'Database'), 'size': (300,600)}),
            ('Detection Opts', elems['Detection Opts'].setParams(pos=('above', 'Map Opts'), size= (300,600))),
            ('File Loader', {'type': 'fileInput', 'size': (300, 300), 'pos': ('above', 'Detection Opts'), 'host': self, 'showFileTree': False}),
            ('Data Plot', elems['Data Plot'].setParams(pos=('bottom', 'Canvas'), size=(700,200))),
            ('Filter Plot', elems['Filter Plot'].setParams(pos=('bottom', 'Data Plot'), size=(700,200))),
            ('Event Table', elems['Output Table'].setParams(pos=('below', 'Filter Plot'), size=(700,200))),
            ('Stats', {'type': 'dataTree', 'size': (700,200), 'pos': ('below', 'Event Table')}),
        ])

        self.initializeElements()
        
        try:
            ## load default chart
            self.flowchart.loadFile(os.path.join(flowchartDir, 'default.fc'))
        except:
            debug.printExc('Error loading default flowchart:')
        
        
        self.detector.flowchart.sigOutputChanged.connect(self.detectorOutputChanged)
        self.flowchart.sigOutputChanged.connect(self.analyzerOutputChanged)
        self.detector.flowchart.sigStateChanged.connect(self.detectorStateChanged)
        self.flowchart.sigStateChanged.connect(self.analyzerStateChanged)
        self.recolorBtn.clicked.connect(self.recolor)
Esempio n. 38
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
Esempio n. 39
0
    def _convertDB(self, dbFile, version):
        ## Convert datbase dbFile from version to the latest version
        
        newFileName = dbFile+"version_upgrade"
        if os.path.exists(newFileName):
            raise Exception("A .version_upgrade for %s already exists. Please delete or rename it" %dbFile)
        if version is None:
            prog = ProgressDialog("Converting database...")
            from AnalysisDatabase_ver0 import AnalysisDatabase as AnalysisDatabaseOld
            oldDb = AnalysisDatabaseOld(dbFile)
            newDb = AnalysisDatabase(newFileName, self.dataModel(), oldDb.baseDir())
            
            dirTypes = ['Day', 'Experiment', 'Slice', 'Cell', 'Site', 'Protocol', 'ProtocolSequence']
            print oldDb.listTables()
            for table in dirTypes:
                if not oldDb.hasTable(table):
                    continue
                for rec in oldDb.select(table):
                    dh = oldDb.baseDir()[rec['Dir']]
                    try:
                        newDb.addDir(dh)
                    except:
                        print "Can't add directory %s from old DB:" % dh.name()
                        debug.printExc()
                    
            total = len(oldDb.select('Photostim_events')) + len(oldDb.select('Photostim_sites'))
            n=0

            for table in ['Photostim_events', 'Photostim_sites', 'Photostim_events2', 'Photostim_sites2']:
                if prog.wasCanceled():
                    break
                if not oldDb.hasTable(table):
                    continue
                schema = oldDb.tableSchema(table)
                ## SourceDir -> ProtocolSequenceDir     type='directory:ProtocolSequence'
                del schema['SourceDir']
                schema['ProtocolSequenceDir'] = 'directory:ProtocolSequence'
                
                ## add column ProtocolDir
                schema['ProtocolDir'] = 'directory:Protocol'
                
                ## SourceFile -> ?        type='file'
                if 'SourceFile' in schema:
                    schema['SourceFile'] = 'file'
                
                owner = oldDb.tableOwner(table)
                newDb.createTable(table, schema, owner=owner)
                
                
                
                records = oldDb.select(table)
                for r in records:
                    if prog.wasCanceled():
                        break
                ##  SourceFile -> convert to filehandle
                    r['SourceFile']= oldDb.getDir('ProtocolSequence', r['SourceDir'])[r['SourceFile']]
                    del r['SourceDir']
                ##  ProtocolDir, ProtocolSequenceDir -> dirHandles
                    #r['ProtocolSequenceDir'] = oldDb.getDir('ProtocolSequence', r['SourceDir'])
                    r['ProtocolDir'] = r['SourceFile'].parent()
                    r['ProtocolSequenceDir'] = self.dataModel().getParent(r['ProtocolDir'], 'ProtocolSequence')
                    n+=1
                    prog.setValue(n/total)
                
                newDb.insert(table, records)
            
            
            oldDb.close()
            newDb.close()
            if not prog.wasCanceled():
                os.rename(dbFile, dbFile+'version_upgrade_backup')
                os.rename(newFileName, dbFile)
        else:
            raise Exception("Don't know how to convert from version %s" % str(version))
Esempio n. 40
0
    def _convertDB(self, dbFile, version):
        ## Convert datbase dbFile from version to the latest version

        newFileName = dbFile + "version_upgrade"
        if os.path.exists(newFileName):
            raise Exception("A .version_upgrade for %s already exists. Please delete or rename it" % dbFile)
        if version is None:
            prog = ProgressDialog("Converting database...")
            from AnalysisDatabase_ver0 import AnalysisDatabase as AnalysisDatabaseOld

            oldDb = AnalysisDatabaseOld(dbFile)
            newDb = AnalysisDatabase(newFileName, self.dataModel(), oldDb.baseDir())

            dirTypes = ["Day", "Experiment", "Slice", "Cell", "Site", "Protocol", "ProtocolSequence"]
            print oldDb.listTables()
            for table in dirTypes:
                if not oldDb.hasTable(table):
                    continue
                for rec in oldDb.select(table):
                    dh = oldDb.baseDir()[rec["Dir"]]
                    try:
                        newDb.addDir(dh)
                    except:
                        print "Can't add directory %s from old DB:" % dh.name()
                        debug.printExc()

            total = len(oldDb.select("Photostim_events")) + len(oldDb.select("Photostim_sites"))
            n = 0

            for table in ["Photostim_events", "Photostim_sites", "Photostim_events2", "Photostim_sites2"]:
                if prog.wasCanceled():
                    break
                if not oldDb.hasTable(table):
                    continue
                schema = oldDb.tableSchema(table)
                ## SourceDir -> ProtocolSequenceDir     type='directory:ProtocolSequence'
                del schema["SourceDir"]
                schema["ProtocolSequenceDir"] = "directory:ProtocolSequence"

                ## add column ProtocolDir
                schema["ProtocolDir"] = "directory:Protocol"

                ## SourceFile -> ?        type='file'
                if "SourceFile" in schema:
                    schema["SourceFile"] = "file"

                owner = oldDb.tableOwner(table)
                newDb.createTable(table, schema, owner=owner)

                records = oldDb.select(table)
                for r in records:
                    if prog.wasCanceled():
                        break
                    ##  SourceFile -> convert to filehandle
                    r["SourceFile"] = oldDb.getDir("ProtocolSequence", r["SourceDir"])[r["SourceFile"]]
                    del r["SourceDir"]
                    ##  ProtocolDir, ProtocolSequenceDir -> dirHandles
                    # r['ProtocolSequenceDir'] = oldDb.getDir('ProtocolSequence', r['SourceDir'])
                    r["ProtocolDir"] = r["SourceFile"].parent()
                    r["ProtocolSequenceDir"] = self.dataModel().getParent(r["ProtocolDir"], "ProtocolSequence")
                    n += 1
                    prog.setValue(n / total)

                newDb.insert(table, records)

            oldDb.close()
            newDb.close()
            if not prog.wasCanceled():
                os.rename(dbFile, dbFile + "version_upgrade_backup")
                os.rename(newFileName, dbFile)
        else:
            raise Exception("Don't know how to convert from version %s" % str(version))
Esempio n. 41
0
    def __init__(self, host):
        AnalysisModule.__init__(self, host)

        flowchartDir = os.path.join(
            os.path.abspath(os.path.split(__file__)[0]), "flowcharts")
        self.flowchart = Flowchart(filePath=flowchartDir)
        self.flowchart.addInput('dataIn')
        self.flowchart.addOutput('results')
        self.flowchart.outputNode._allowAddInput = False  ## make sure all data is coming out of output['results']

        try:
            ## load default chart
            self.flowchart.loadFile(os.path.join(flowchartDir, 'default.fc'))
        except:
            debug.printExc('Error loading default flowchart:')

        tables = OrderedDict([(self.dbIdentity + '.traces',
                               'TimecourseAnalyzer_traces')])
        self.dbGui = DatabaseGui(dm=host.dataManager(), tables=tables)

        self.ctrl = Qt.QWidget()
        self.ctrl.setLayout(Qt.QVBoxLayout())
        self.analyzeBtn = Qt.QPushButton('Analyze')
        self.storeToDBBtn = Qt.QPushButton('Store to DB')
        self.ctrl.layout().addWidget(self.analyzeBtn)
        self.ctrl.layout().addWidget(self.storeToDBBtn)

        self._elements_ = OrderedDict([('Database', {
            'type': 'ctrl',
            'object': self.dbGui,
            'size': (100, 100)
        }),
                                       ('Analysis Options', {
                                           'type': 'ctrl',
                                           'object': self.flowchart.widget(),
                                           'pos': ('above', 'Database'),
                                           'size': (100, 400)
                                       }),
                                       ('File Loader', {
                                           'type': 'fileInput',
                                           'size': (100, 100),
                                           'pos':
                                           ('above', 'Analysis Options'),
                                           'host': self
                                       }),
                                       ('Experiment Plot', {
                                           'type': 'plot',
                                           'pos': ('right', 'File Loader'),
                                           'size': (400, 100)
                                       }),
                                       ('Traces Plot', {
                                           'type': 'plot',
                                           'pos':
                                           ('bottom', 'Experiment Plot'),
                                           'size': (400, 200)
                                       }),
                                       ('Results Plot', {
                                           'type': 'plot',
                                           'pos': ('bottom', 'Traces Plot'),
                                           'size': (400, 200)
                                       }),
                                       ('Results Table', {
                                           'type': 'table',
                                           'pos': ('bottom', 'Traces Plot'),
                                           'size': (400, 200)
                                       }),
                                       ('Store Ctrl', {
                                           'type': 'ctrl',
                                           'object': self.ctrl,
                                           'size': (100, 100),
                                           'pos': ('bottom', 'File Loader')
                                       })])
        self.initializeElements()

        self.fileLoader = self.getElement('File Loader', create=True)
        self.exptPlot = self.getElement('Experiment Plot', create=True)
        self.tracesPlot = self.getElement('Traces Plot', create=True)
        self.resultsTable = self.getElement('Results Table', create=True)
        self.resultsTable.setSortingEnabled(False)
        self.resultsPlot = self.getElement('Results Plot', create=True)
        self.resultsPlot.getViewBox().setXLink(self.exptPlot.getViewBox(
        ))  ## link the x-axes of the exptPlot and the resultsPlot

        ### initialize variables
        self.expStart = 0
        self.traces = np.array([],
                               dtype=[('timestamp', float), ('data', object),
                                      ('fileHandle', object),
                                      ('results', object)])
        self.files = []

        self.traceSelectRgn = pg.LinearRegionItem()
        self.traceSelectRgn.setRegion([0, 60])
        self.exptPlot.addItem(self.traceSelectRgn)
        self.traceSelectRgn.sigRegionChanged.connect(self.updateTracesPlot)
        #self.traceSelectRgn.sigRegionChangeFinished.connect(self.updateAnalysis)
        #self.flowchart.sigOutputChanged.connect(self.flowchartOutputChanged)

        #self.addRegionParam = pg.parametertree.Parameter.create(name="Add Region", type='action')
        #self.paramTree.addParameters(self.addRegionParam)
        #self.addRegionParam.sigActivated.connect(self.newRegionRequested)
        self.analyzeBtn.clicked.connect(self.analyzeBtnClicked)
        self.storeToDBBtn.clicked.connect(self.storeToDBBtnClicked)
        self.flowchart.sigChartLoaded.connect(self.connectPlots)
        self.fileLoader.sigClearRequested.connect(self.clearFilesRequested)
Esempio n. 42
0
 def recordingFailed(self):
     self.endStack()
     printExc("Recording failed! See console for error message.")
Esempio n. 43
0
    def __init__(self, host):
        AnalysisModule.__init__(self, host)
        if self.dataModel is None:
            raise Exception(
                "Photostim analysis module requires a data model, but none is loaded yet."
            )
        self.dbIdentity = "Photostim"  ## how we identify to the database; this determines which tables we own
        self.selectedSpot = None

        ## setup analysis flowchart
        modPath = os.path.abspath(os.path.split(__file__)[0])
        flowchartDir = os.path.join(modPath, "analysis_fc")
        self.flowchart = Flowchart(filePath=flowchartDir)
        self.flowchart.addInput('events')
        self.flowchart.addInput('regions')
        self.flowchart.addInput('fileHandle')
        self.flowchart.addOutput('dataOut')
        self.analysisCtrl = self.flowchart.widget()

        ## color mapper
        self.mapper = ColorMapper.ColorMapper(
            filePath=os.path.join(modPath, "colormaps"))
        self.mapCtrl = QtGui.QWidget()
        self.mapLayout = QtGui.QVBoxLayout()
        self.mapCtrl.setLayout(self.mapLayout)
        self.mapLayout.splitter = QtGui.QSplitter()
        self.mapLayout.splitter.setOrientation(QtCore.Qt.Vertical)
        self.mapLayout.splitter.setContentsMargins(0, 0, 0, 0)
        self.mapLayout.addWidget(self.mapLayout.splitter)
        self.mapLayout.splitter.addWidget(self.analysisCtrl)
        #self.mapLayout.splitter.addWidget(QtGui.QSplitter())
        self.mapLayout.splitter.addWidget(self.mapper)
        #self.mapLayout.splitter.addWidget(self.recolorBtn)

        self.recolorLayout = QtGui.QHBoxLayout()
        self.recolorWidget = QtGui.QWidget()
        self.mapLayout.splitter.addWidget(self.recolorWidget)
        self.recolorWidget.setLayout(self.recolorLayout)
        self.recolorBtn = QtGui.QPushButton('Recolor')
        self.recolorLayout.addWidget(self.recolorBtn)
        self.recolorParallelCheck = QtGui.QCheckBox('Parallel')
        self.recolorParallelCheck.setChecked(True)
        self.recolorLayout.addWidget(self.recolorParallelCheck)

        ## scatter plot
        self.scatterPlot = ScatterPlotter()
        self.scatterPlot.sigClicked.connect(self.scatterPlotClicked)

        ## setup map DB ctrl
        self.dbCtrl = DBCtrl(self, self.dbIdentity)

        ## storage for map data
        #self.scanItems = {}
        self.scans = []
        #self.seriesScans = {}
        self.maps = []

        ## create event detector
        fcDir = os.path.join(os.path.abspath(os.path.split(__file__)[0]),
                             "detector_fc")
        self.detector = EventDetector.EventDetector(
            host, flowchartDir=fcDir, dbIdentity=self.dbIdentity + '.events')

        ## override some of its elements
        self.detector.setElement('File Loader', self)
        self.detector.setElement('Database', self.dbCtrl)

        ## Create element list, importing some gui elements from event detector
        elems = self.detector.listElements()
        self._elements_ = OrderedDict([
            ('Database', {
                'type': 'ctrl',
                'object': self.dbCtrl,
                'size': (300, 600)
            }),
            ('Scatter Plot', {
                'type': 'ctrl',
                'object': self.scatterPlot,
                'pos': ('right', ),
                'size': (700, 400)
            }),
            ('Canvas', {
                'type': 'canvas',
                'pos': ('above', 'Scatter Plot'),
                'size': (700, 400),
                'allowTransforms': False,
                'hideCtrl': True,
                'args': {
                    'name': 'Photostim'
                }
            }),
            #('Maps', {'type': 'ctrl', 'pos': ('bottom', 'Database'), 'size': (200,200), 'object': self.mapDBCtrl}),
            ('Map Opts', {
                'type': 'ctrl',
                'object': self.mapCtrl,
                'pos': ('above', 'Database'),
                'size': (300, 600)
            }),
            ('Detection Opts',
             elems['Detection Opts'].setParams(pos=('above', 'Map Opts'),
                                               size=(300, 600))),
            ('File Loader', {
                'type': 'fileInput',
                'size': (300, 300),
                'pos': ('above', 'Detection Opts'),
                'host': self,
                'showFileTree': False
            }),
            ('Data Plot', elems['Data Plot'].setParams(pos=('bottom',
                                                            'Canvas'),
                                                       size=(700, 200))),
            ('Filter Plot', elems['Filter Plot'].setParams(pos=('bottom',
                                                                'Data Plot'),
                                                           size=(700, 200))),
            ('Event Table',
             elems['Output Table'].setParams(pos=('below', 'Filter Plot'),
                                             size=(700, 200))),
            ('Stats', {
                'type': 'dataTree',
                'size': (700, 200),
                'pos': ('below', 'Event Table')
            }),
        ])

        self.initializeElements()

        try:
            ## load default chart
            self.flowchart.loadFile(os.path.join(flowchartDir, 'default.fc'))
        except:
            debug.printExc('Error loading default flowchart:')

        self.detector.flowchart.sigOutputChanged.connect(
            self.detectorOutputChanged)
        self.flowchart.sigOutputChanged.connect(self.analyzerOutputChanged)
        self.detector.flowchart.sigStateChanged.connect(
            self.detectorStateChanged)
        self.flowchart.sigStateChanged.connect(self.analyzerStateChanged)
        self.recolorBtn.clicked.connect(self.recolor)
Esempio n. 44
0
    def __init__(self, image=None, **opts):
        """
        CanvasItem displaying an image. 
        The image may be 2 or 3-dimensional.
        Options:
            image: May be a fileHandle, ndarray, or GraphicsItem.
            handle: May optionally be specified in place of image

        """

        ## If no image was specified, check for a file handle..
        if image is None:
            image = opts.get('handle', None)

        item = None
        self.data = None
        self.currentT = None

        if isinstance(image, QtGui.QGraphicsItem):
            item = image
        elif isinstance(image, np.ndarray):
            self.data = image
        elif isinstance(image, DataManager.FileHandle):
            opts['handle'] = image
            self.handle = image
            self.data = self.handle.read()

            if 'name' not in opts:
                opts['name'] = self.handle.shortName()

            try:
                if 'transform' in self.handle.info():
                    tr = pg.SRTTransform3D(self.handle.info()['transform'])
                    tr = pg.SRTTransform(tr)  ## convert to 2D
                    opts['pos'] = tr.getTranslation()
                    opts['scale'] = tr.getScale()
                    opts['angle'] = tr.getRotation()
                else:  ## check for older info formats
                    if 'imagePosition' in self.handle.info():
                        opts['scale'] = self.handle.info()['pixelSize']
                        opts['pos'] = self.handle.info()['imagePosition']
                    elif 'Downsample' in self.handle.info():
                        ### Needed to support an older format stored by 2p imager
                        if 'pixelSize' in self.handle.info():
                            opts['scale'] = self.handle.info()['pixelSize']
                        if 'microscope' in self.handle.info():
                            m = self.handle.info()['microscope']
                            print 'm: ', m
                            print 'mpos: ', m['position']
                            opts['pos'] = m['position'][0:2]
                        else:
                            info = self.data._info[-1]
                            opts['pos'] = info.get('imagePosition', None)
                    elif hasattr(self.data, '_info'):
                        info = self.data._info[-1]
                        opts['scale'] = info.get('pixelSize', None)
                        opts['pos'] = info.get('imagePosition', None)
                    else:
                        opts['defaultUserTransform'] = {'scale': (1e-5, 1e-5)}
                        opts['scalable'] = True
            except:
                debug.printExc(
                    'Error reading transformation for image file %s:' %
                    image.name())

        if item is None:
            item = pg.ImageItem()
        CanvasItem.__init__(self, item, **opts)

        self.histogram = pg.PlotWidget()
        self.blockHistogram = False
        self.histogram.setMaximumHeight(100)
        self.levelRgn = pg.LinearRegionItem()
        self.histogram.addItem(self.levelRgn)
        self.updateHistogram(autoLevels=True)

        # addWidget arguments: row, column, rowspan, colspan
        self.layout.addWidget(self.histogram, self.layout.rowCount(), 0, 1, 3)

        self.timeSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
        #self.timeSlider.setMinimum(0)
        #self.timeSlider.setMaximum(self.data.shape[0]-1)
        self.layout.addWidget(self.timeSlider, self.layout.rowCount(), 0, 1, 3)
        self.timeSlider.valueChanged.connect(self.timeChanged)
        self.timeSlider.sliderPressed.connect(self.timeSliderPressed)
        self.timeSlider.sliderReleased.connect(self.timeSliderReleased)
        thisRow = self.layout.rowCount()

        self.edgeBtn = QtGui.QPushButton('Edge')
        self.edgeBtn.clicked.connect(self.edgeClicked)
        self.layout.addWidget(self.edgeBtn, thisRow, 0, 1, 1)

        self.meanBtn = QtGui.QPushButton('Mean')
        self.meanBtn.clicked.connect(self.meanClicked)
        self.layout.addWidget(self.meanBtn, thisRow + 1, 0, 1, 1)

        self.tvBtn = QtGui.QPushButton('tv denoise')
        self.tvBtn.clicked.connect(self.tvClicked)
        self.layout.addWidget(self.tvBtn, thisRow + 2, 0, 1, 1)

        self.maxBtn = QtGui.QPushButton('Max no Filter')
        self.maxBtn.clicked.connect(self.maxClicked)
        self.layout.addWidget(self.maxBtn, thisRow, 1, 1, 1)

        self.maxBtn2 = QtGui.QPushButton('Max w/Gaussian')
        self.maxBtn2.clicked.connect(self.max2Clicked)
        self.layout.addWidget(self.maxBtn2, thisRow + 1, 1, 1, 1)

        self.maxMedianBtn = QtGui.QPushButton('Max w/Median')
        self.maxMedianBtn.clicked.connect(self.maxMedianClicked)
        self.layout.addWidget(self.maxMedianBtn, thisRow + 2, 1, 1, 1)

        self.filterOrder = QtGui.QComboBox()
        self.filterLabel = QtGui.QLabel('Order')
        for n in range(1, 11):
            self.filterOrder.addItem("%d" % n)
        self.layout.addWidget(self.filterLabel, thisRow + 3, 2, 1, 1)
        self.layout.addWidget(self.filterOrder, thisRow + 3, 3, 1, 1)

        self.zPlanes = QtGui.QComboBox()
        self.zPlanesLabel = QtGui.QLabel('# planes')
        for s in ['All', '1', '2', '3', '4', '5']:
            self.zPlanes.addItem("%s" % s)
        self.layout.addWidget(self.zPlanesLabel, thisRow + 3, 0, 1, 1)
        self.layout.addWidget(self.zPlanes, thisRow + 3, 1, 1, 1)

        ## controls that only appear if there is a time axis
        self.timeControls = [
            self.timeSlider, self.edgeBtn, self.maxBtn, self.meanBtn,
            self.maxBtn2, self.maxMedianBtn, self.filterOrder, self.zPlanes
        ]

        if self.data is not None:
            self.updateImage(self.data)

        self.graphicsItem().sigImageChanged.connect(self.updateHistogram)
        self.levelRgn.sigRegionChanged.connect(self.levelsChanged)
        self.levelRgn.sigRegionChangeFinished.connect(
            self.levelsChangeFinished)
Esempio n. 45
0
    def __init__(self, image=None, **opts):
        """
        CanvasItem displaying an image. 
        The image may be 2 or 3-dimensional.
        Options:
            image: May be a fileHandle, ndarray, or GraphicsItem.
            handle: May optionally be specified in place of image

        """

        ## If no image was specified, check for a file handle..
        if image is None:
            image = opts.get('handle', None)

        item = None
        self.data = None
        self.currentT = None
        
        if isinstance(image, QtGui.QGraphicsItem):
            item = image
        elif isinstance(image, np.ndarray):
            self.data = image
        elif isinstance(image, DataManager.FileHandle):
            opts['handle'] = image
            self.handle = image
            self.data = self.handle.read()

            if 'name' not in opts:
                opts['name'] = self.handle.shortName()

            try:
                if 'transform' in self.handle.info():
                    tr = pg.SRTTransform3D(self.handle.info()['transform'])
                    tr = pg.SRTTransform(tr)  ## convert to 2D
                    opts['pos'] = tr.getTranslation()
                    opts['scale'] = tr.getScale()
                    opts['angle'] = tr.getRotation()
                else:  ## check for older info formats
                    if 'imagePosition' in self.handle.info():
                        opts['scale'] = self.handle.info()['pixelSize']
                        opts['pos'] = self.handle.info()['imagePosition']
                    elif 'Downsample' in self.handle.info():
                        ### Needed to support an older format stored by 2p imager
                        if 'pixelSize' in self.handle.info():
                            opts['scale'] = self.handle.info()['pixelSize']
                        if 'microscope' in self.handle.info():
                            m = self.handle.info()['microscope']
                            print 'm: ',m
                            print 'mpos: ', m['position']
                            opts['pos'] = m['position'][0:2]
                        else:
                            info = self.data._info[-1]
                            opts['pos'] = info.get('imagePosition', None)
                    elif hasattr(self.data, '_info'):
                        info = self.data._info[-1]
                        opts['scale'] = info.get('pixelSize', None)
                        opts['pos'] = info.get('imagePosition', None)
                    else:
                        opts['defaultUserTransform'] = {'scale': (1e-5, 1e-5)}
                        opts['scalable'] = True
            except:
                debug.printExc('Error reading transformation for image file %s:' % image.name())

        if item is None:
            item = pg.ImageItem()
        CanvasItem.__init__(self, item, **opts)

        self.histogram = pg.PlotWidget()
        self.blockHistogram = False
        self.histogram.setMaximumHeight(100)
        self.levelRgn = pg.LinearRegionItem()
        self.histogram.addItem(self.levelRgn)
        self.updateHistogram(autoLevels=True)

        # addWidget arguments: row, column, rowspan, colspan 
        self.layout.addWidget(self.histogram, self.layout.rowCount(), 0, 1, 3)

        self.timeSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
        #self.timeSlider.setMinimum(0)
        #self.timeSlider.setMaximum(self.data.shape[0]-1)
        self.layout.addWidget(self.timeSlider, self.layout.rowCount(), 0, 1, 3)
        self.timeSlider.valueChanged.connect(self.timeChanged)
        self.timeSlider.sliderPressed.connect(self.timeSliderPressed)
        self.timeSlider.sliderReleased.connect(self.timeSliderReleased)
        thisRow = self.layout.rowCount()

        self.edgeBtn = QtGui.QPushButton('Edge')
        self.edgeBtn.clicked.connect(self.edgeClicked)
        self.layout.addWidget(self.edgeBtn, thisRow, 0, 1, 1)

        self.meanBtn = QtGui.QPushButton('Mean')
        self.meanBtn.clicked.connect(self.meanClicked)
        self.layout.addWidget(self.meanBtn, thisRow+1, 0, 1, 1)

        self.tvBtn = QtGui.QPushButton('tv denoise')
        self.tvBtn.clicked.connect(self.tvClicked)
        self.layout.addWidget(self.tvBtn, thisRow+2, 0, 1, 1)

        self.maxBtn = QtGui.QPushButton('Max no Filter')
        self.maxBtn.clicked.connect(self.maxClicked)
        self.layout.addWidget(self.maxBtn, thisRow, 1, 1, 1)

        self.maxBtn2 = QtGui.QPushButton('Max w/Gaussian')
        self.maxBtn2.clicked.connect(self.max2Clicked)
        self.layout.addWidget(self.maxBtn2, thisRow+1, 1, 1, 1)

        self.maxMedianBtn = QtGui.QPushButton('Max w/Median')
        self.maxMedianBtn.clicked.connect(self.maxMedianClicked)
        self.layout.addWidget(self.maxMedianBtn, thisRow+2, 1, 1, 1)

        self.filterOrder = QtGui.QComboBox()
        self.filterLabel = QtGui.QLabel('Order')
        for n in range(1,11):
            self.filterOrder.addItem("%d" % n)
        self.layout.addWidget(self.filterLabel, thisRow+3, 2, 1, 1)
        self.layout.addWidget(self.filterOrder, thisRow+3, 3, 1, 1)
        
        self.zPlanes = QtGui.QComboBox()
        self.zPlanesLabel = QtGui.QLabel('# planes')
        for s in ['All', '1', '2', '3', '4', '5']:
            self.zPlanes.addItem("%s" % s)
        self.layout.addWidget(self.zPlanesLabel, thisRow+3, 0, 1, 1)
        self.layout.addWidget(self.zPlanes, thisRow + 3, 1, 1, 1)

        ## controls that only appear if there is a time axis
        self.timeControls = [self.timeSlider, self.edgeBtn, self.maxBtn, self.meanBtn, self.maxBtn2,
            self.maxMedianBtn, self.filterOrder, self.zPlanes]

        if self.data is not None:
            self.updateImage(self.data)


        self.graphicsItem().sigImageChanged.connect(self.updateHistogram)
        self.levelRgn.sigRegionChanged.connect(self.levelsChanged)
        self.levelRgn.sigRegionChangeFinished.connect(self.levelsChangeFinished)
Esempio n. 46
0
    def run(self):
        self.stopThread = False
        #self.sp = serial.Serial(int(self.port), baudrate=self.baud, bytesize=serial.EIGHTBITS)
        #time.sleep(3) ## Wait a few seconds for the mouse to say hello
        ## clear buffer before starting
        #if self.sp.inWaiting() > 0:
            #print "Discarding %d bytes" % self.sp.inWaiting()
            #self.sp.read(self.sp.inWaiting())
        #import wingdbstub
        print "  Starting MP285 thread: 0x%x" % int(QtCore.QThread.currentThreadId())
        #import sip
        #print "    also known as 0x%x" % sip.unwrapinstance(self)
        velocity = np.array([0,0,0])
        pos = [0,0,0]
        
        try:
            self.getImmediatePos()
            monitor = True
        except:
            debug.printExc("Sutter MP285: Cannot determine position:")
            monitor = False
        
        while True:
            try:
                ## Lock and copy state to local variables
                with self.lock:
                    update = self.update
                    self.update = False
                    limits = deepcopy(self.limits)
                    maxSpeed = self.maxSpeed
                    newVelocity = np.array(self.velocity[:])
                    resolution = self.resolution
                    limitChanged = self.limitChanged
                    self.limitChanged = False
                    
                ## if limits have changed, inform the device
                if monitor and limitChanged:   ## monitor is only true if this is a customized device with limit checking
                    self.sendLimits()
                
                ## If requested velocity is different from the current velocity, handle that.
                if np.any(newVelocity != velocity):
                    speed = np.clip(np.sum(newVelocity**2)**0.5, 0., 1.)   ## should always be 0.0-1.0
                    #print "new velocity:", newVelocity, "speed:", speed
                    
                    if speed == 0:
                        nv = np.array([0,0,0])
                    else:
                        nv = newVelocity/speed
                        
                    speed = np.clip(speed, 0, maxSpeed)
                    #print "final speed:", speed
                    
                    ## stop current move, get position, start new move
                    #print "stop.."
                    self.stopMove()
                    #print "stop done."
                    
                    #print "getpos..."
                    pos1 = self.readPosition()
                    if pos1 is not None:
                        
                        if speed > 0:
                            #print "   set new velocity"
                            self.writeVelocity(speed, nv, limits=limits, pos=pos1, resolution=resolution)
                            #print "   done"
                            
                        ## report current position
                        
                            
                        velocity = newVelocity
                    #print "done"
                
                ## If velocity is 0, we can do some position checks
                if np.all(velocity == 0):
                    newPos = None
                    if update:
                        newPos = self.readPosition()
                    elif monitor:
                        newPos = self.getImmediatePos()
    
                    if newPos is not None: ## If position has changed, emit a signal.
        
                        change = [newPos[i] - pos[i] for i in range(len(newPos))]
                        pos = newPos
        
                        if any(change):
                            #self.emit(QtCore.SIGNAL('positionChanged'), {'rel': change, 'abs': self.pos})
                            self.sigPositionChanged.emit({'rel': change, 'abs': pos})
                else:
                    ## moving; make a guess about the current position
                    pass
            except:
                pass
                debug.printExc("Error in MP285 thread:")
                
            self.lock.lock()
            if self.stopThread:
                self.lock.unlock()
                break
            self.lock.unlock()
            time.sleep(0.02)


        self.mp285.close()
Esempio n. 47
0
    def __init__(self, dm, config, name):

        # Generate config to use for DAQ
        daqConfig = {}

        for ch in ["GainChannel", "LPFChannel", "ModeChannel"]:
            if ch not in config:
                continue
            daqConfig[ch] = config[ch].copy()
        # if 'GainChannel' in config:
        #    daqConfig['gain'] = {'type': 'ai', 'channel': config['GainChannel']}
        # if 'LPFChannel' in config:
        #    daqConfig['LPF'] = {'type': 'ai', 'channel': config['LPFChannel'], 'units': 'Hz'}
        if "ScaledSignal" in config:
            # daqConfig['primary'] = {'type': 'ai', 'channel': config['ScaledSignal']}
            daqConfig["primary"] = config["ScaledSignal"]
            if config["ScaledSignal"].get("type", None) != "ai":
                raise Exception("AxoPatch200: ScaledSignal configuration must have type:'ai'")
        if "Command" in config:
            # daqConfig['command'] = {'type': 'ao', 'channel': config['Command']}
            daqConfig["command"] = config["Command"]
            if config["Command"].get("type", None) != "ao":
                raise Exception("AxoPatch200: ScaledSignal configuration must have type:'ao'")

        ## Note that both of these channels can be present, but we will only ever record from one at a time.
        ## Usually, we'll record from "I OUTPUT" in current clamp and "10 Vm OUTPUT" in voltage clamp.
        if "SecondaryVCSignal" in config:
            self.hasSecondaryChannel = True
            # daqConfig['secondary'] = {'type': 'ai', 'channel': config['SecondaryVCSignal']}
            daqConfig["secondary"] = config["SecondaryVCSignal"]
            if config["SecondaryVCSignal"].get("type", None) != "ai":
                raise Exception("AxoPatch200: SecondaryVCSignal configuration must have type:'ai'")
        elif "SecondaryICSignal" in config:
            self.hasSecondaryChannel = True
            # daqConfig['secondary'] = {'type': 'ai', 'channel': config['SecondaryICSignal']}
            daqConfig["secondary"] = config["SecondaryICSignal"]
            if config["SecondaryICSignal"].get("type", None) != "ai":
                raise Exception("AxoPatch200: SecondaryICSignal configuration must have type:'ai'")
        else:
            self.hasSecondaryChannel = False

        self.holding = {"vc": config.get("vcHolding", -0.05), "ic": config.get("icHolding", 0.0)}

        self.config = config
        self.modeLock = Mutex(Mutex.Recursive)  ## protects self.mdCanceled
        self.devLock = Mutex(Mutex.Recursive)  ## protects self.holding, possibly self.config, ..others, perhaps?
        self.mdCanceled = False

        DAQGeneric.__init__(self, dm, daqConfig, name)

        self.modeDialog = QtGui.QMessageBox()
        self.modeDialog.hide()
        self.modeDialog.setModal(False)
        self.modeDialog.setWindowTitle("Mode Switch Request")
        self.modeDialog.addButton(self.modeDialog.Cancel)
        self.modeDialog.buttonClicked.connect(self.modeDialogClicked)

        self.sigShowModeDialog.connect(self.showModeDialog)
        self.sigHideModeDialog.connect(self.hideModeDialog)

        try:
            self.setHolding()
        except:
            printExc("Error while setting holding value:")

        dm.declareInterface(name, ["clamp"], self)