Exemple #1
0
    def __init__(self):
        self.telegraph = None
        if MultiClamp.INSTANCE is not None:
            raise Exception(
                "Already created MultiClamp driver object; use MultiClamp.INSTANCE"
            )
        self.handle = None
        self.lock = threading.RLock()

        self.channels = {}
        self.chanDesc = {}
        self.connect()

        self.telegraph = MultiClampTelegraph(self.chanDesc,
                                             self.telegraphMessage)
        MultiClamp.INSTANCE = self

        atexit.register(self.quit)
Exemple #2
0
 def __init__(self):
     self.telegraph = None
     if MultiClamp.INSTANCE is not None:
         raise Exception("Already created MultiClamp driver object; use MultiClamp.INSTANCE")
     self.handle = None
     self.lock = threading.RLock()
     #self.lock = Mutex(Mutex.Recursive)
     #self.devStates = []  ## Stores basic state of devices reported by telegraph
     
     self.channels = {} 
     self.chanDesc = {}  
     self.connect()
     
     self.telegraph = MultiClampTelegraph(self.chanDesc, self.telegraphMessage)
     MultiClamp.INSTANCE = self
Exemple #3
0
class MultiClamp:
    """Class used to interface with remote multiclamp server.
    Only one instance of this class should be created.
    
    Example usage:
        mc = MultiClamp.instance()
        devs = mc.listDevices()
        chan0 = mc.getChannel(devs[0])
        chan0.setMode('IC')
        signal, gain, units = chan0.getSignalInfo()
    """
    INSTANCE = None

    def __init__(self):
        self.telegraph = None
        if MultiClamp.INSTANCE is not None:
            raise Exception(
                "Already created MultiClamp driver object; use MultiClamp.INSTANCE"
            )
        self.handle = None
        self.lock = threading.RLock()

        self.channels = {}
        self.chanDesc = {}
        self.connect()

        self.telegraph = MultiClampTelegraph(self.chanDesc,
                                             self.telegraphMessage)
        MultiClamp.INSTANCE = self

        atexit.register(self.quit)

    def quit(self):
        ## do other things to shut down driver?
        self.disconnect()
        if self.telegraph is not None:
            self.telegraph.quit()
        MultiClamp.INSTANCE = None

    @staticmethod
    def instance():
        return MultiClamp.INSTANCE

    def getChannel(self, channel, callback=None):
        """Return a MultiClampChannel object for the specified device/channel. The
        channel argument should be the same as a single item from listDevices().
        The callback will be called when certain (but not any) changes are made
        to the multiclamp state."""
        if channel not in self.channels:
            raise Exception(
                "No channel with description '%s'. Options are %s" %
                (str(channel), str(self.listChannels())))

        ch = self.channels[channel]
        if callback is not None:
            ch.setCallback(callback)
        return ch

    def listChannels(self):
        """Return a list of strings used to identify all devices/channels.
        These strings should be used to identify the same channel across invocations."""
        return self.channels.keys()

    def connect(self):
        """(re)create connection to commander."""
        #print "connect to commander.."
        with self.lock:
            if self.handle is not None:
                #print "   disconnect first"
                self.disconnect()
            (self.handle, err) = axlib.CreateObject()
            if self.handle == 0:
                self.handle = None
                self.raiseError("Error while initializing Axon library:", err)
            self.findDevices()

            #print "    now connected:", self.chanDesc

    def disconnect(self):
        """Destroy connection to commander"""
        with self.lock:
            if self.handle is not None and axlib is not None:
                axlib.DestroyObject(self.handle)
                self.handle = None

    def findDevices(self):
        while True:
            ch = self.findMultiClamp()
            if ch is None:
                break
            else:
                ## Make sure the order of keys is well defined; string must be identical every time.
                ch1 = ch.copy()
                ch1['model'] = MODELS[ch1['model']]
                if ch1['model'] == 'MC700A':
                    strDesc = ",".join(
                        "%s:%s" % (k, ch1[k])
                        for k in ['model', 'com', 'dev', 'chan'])
                elif ch1['model'] == 'MC700B':
                    strDesc = ",".join("%s:%s" % (k, ch1[k])
                                       for k in ['model', 'sn', 'chan'])
                if strDesc not in self.channels:
                    self.channels[strDesc] = MultiClampChannel(self, ch)
                self.chanDesc[strDesc] = ch

    def findMultiClamp(self):
        if len(self.channels) == 0:
            fn = 'FindFirstMultiClamp'
        else:
            fn = 'FindNextMultiClamp'

        try:
            serial = create_string_buffer('\0' * 16)
            ret = self.call(fn, pszSerialNum=serial, uBufSize=16)
        except:
            if sys.exc_info(
            )[1][0] == 6000:  ## We have reached the end of the device list
                return None
            raise

        desc = {
            'sn': ret['pszSerialNum'],
            'model': ret['puModel'],
            'com': ret['puCOMPortID'],
            'dev': ret['puDeviceID'],
            'chan': ret['puChannelID']
        }

        return desc

    def call(
        self, fName, *args, **kargs
    ):  ## call is only used for functions that return a bool error status and have a pnError argument passed by reference.
        with self.lock:
            ret = axlib('functions', fName)(self.handle, *args, **kargs)
        if ret() == 0:
            funcStr = "%s(%s)" % (fName, ', '.join(
                map(str, args) + ["%s=%s" % (k, str(kargs[k]))
                                  for k in kargs]))
            self.raiseError(
                "Error while running function  %s\n      Error:" % funcStr,
                ret['pnError'])

        return ret

    def raiseError(self, msg, err):
        raise Exception(err, msg + " " + self.errString(err))

    def errString(self, err):
        try:
            return axlib.BuildErrorText(self.handle, err,
                                        create_string_buffer('\0' * 256),
                                        256)['sTxtBuf']
        except:
            sys.excepthook(*sys.exc_info())
            return "<could not generate error message>"

    def telegraphMessage(self, msg, chID=None, state=None):
        if msg == 'update':
            self.channels[chID].updateState(state)
        elif msg == 'reconnect':
            self.connect()
Exemple #4
0
class MultiClamp:
    """Class used to interface with remote multiclamp server.
    Only one instance of this class should be created.
    
    Example usage:
        mc = MultiClamp.instance()
        devs = mc.listDevices()
        chan0 = mc.getChannel(devs[0])
        chan0.setMode('IC')
        signal, gain, units = chan0.getSignalInfo()
    """
    INSTANCE = None
    
    def __init__(self):
        self.telegraph = None
        if MultiClamp.INSTANCE is not None:
            raise Exception("Already created MultiClamp driver object; use MultiClamp.INSTANCE")
        self.handle = None
        self.lock = threading.RLock()
        #self.lock = Mutex(Mutex.Recursive)
        #self.devStates = []  ## Stores basic state of devices reported by telegraph
        
        self.channels = {} 
        self.chanDesc = {}  
        self.connect()
        
        self.telegraph = MultiClampTelegraph(self.chanDesc, self.telegraphMessage)
        MultiClamp.INSTANCE = self
    
    def __del__(self):
        self.quit()
        
    
    def quit(self):
        ## do other things to shut down driver?
        self.disconnect()
        if self.telegraph is not None:
            self.telegraph.quit()
        MultiClamp.INSTANCE = None
    
    @staticmethod
    def instance():
        return MultiClamp.INSTANCE
    
    def getChannel(self, channel, callback=None):
        """Return a MultiClampChannel object for the specified device/channel. The
        channel argument should be the same as a single item from listDevices().
        The callback will be called when certain (but not any) changes are made
        to the multiclamp state."""
        if channel not in self.channels:
            raise Exception("No channel with description '%s'. Options are %s" % (str(channel), str(self.listChannels())))
            
        ch = self.channels[channel]
        if callback is not None:
            ch.setCallback(callback)
        return ch
    
    
    def listChannels(self):
        """Return a list of strings used to identify all devices/channels.
        These strings should be used to identify the same channel across invocations."""
        return self.channels.keys()
    
    def connect(self):
        """(re)create connection to commander."""
        #print "connect to commander.."
        with self.lock:
            if self.handle is not None:
                #print "   disconnect first"
                self.disconnect()
            (self.handle, err) = axlib.CreateObject()
            if self.handle == 0:
                self.handle = None
                self.raiseError("Error while initializing Axon library:", err)
            self.findDevices()
            
            #print "    now connected:", self.chanDesc
            
    def disconnect(self):
        """Destroy connection to commander"""
        with self.lock:
            if self.handle is not None and axlib is not None:
                axlib.DestroyObject(self.handle)
                self.handle = None

    
    def findDevices(self):
        while True:
            ch = self.findMultiClamp()
            if ch is None:
                break
            else:
                ## Make sure the order of keys is well defined; string must be identical every time.
                ch1 = ch.copy()
                ch1['model'] = MODELS[ch1['model']]
                if ch1['model'] == 'MC700A':
                    strDesc = ",".join("%s:%s" % (k, ch1[k]) for k in ['model', 'com', 'dev', 'chan'])  
                elif ch1['model'] == 'MC700B':
                    strDesc = ",".join("%s:%s" % (k, ch1[k]) for k in ['model', 'sn', 'chan'])  
                if strDesc not in self.channels:
                    self.channels[strDesc] = MultiClampChannel(self, ch)
                self.chanDesc[strDesc] = ch


    def findMultiClamp(self):
        if len(self.channels) == 0:
            fn = 'FindFirstMultiClamp'
        else:
            fn = 'FindNextMultiClamp'
            
        try:
            serial = create_string_buffer('\0'*16)
            ret = self.call(fn, pszSerialNum=serial, uBufSize=16)
        except:
            if sys.exc_info()[1][0] == 6000:  ## We have reached the end of the device list
                return None
            raise
        
        desc = {'sn': ret['pszSerialNum'], 'model': ret['puModel'], 'com': ret['puCOMPortID'], 'dev': ret['puDeviceID'], 'chan': ret['puChannelID']}
        
        #if MODELS.has_key(desc['model']):
            #desc['model'] = MODELS[desc['model']]
        #else:
            #desc['model'] = 'UNKNOWN'
        return desc



    def call(self, fName, *args, **kargs):   ## call is only used for functions that return a bool error status and have a pnError argument passed by reference.
        with self.lock:
            ret = axlib('functions', fName)(self.handle, *args, **kargs)
        if ret() == 0:
            funcStr = "%s(%s)" % (fName, ', '.join(map(str, args) + ["%s=%s" % (k, str(kargs[k])) for k in kargs]))
            self.raiseError("Error while running function  %s\n      Error:" % funcStr, ret['pnError'])
            
        return ret
    
    def raiseError(self, msg, err):
        raise Exception(err, msg + " " + self.errString(err))

    def errString(self, err):
        try:
            return axlib.BuildErrorText(self.handle, err, create_string_buffer('\0'*256), 256)['sTxtBuf']
        except:
            sys.excepthook(*sys.exc_info())
            return "<could not generate error message>"

    def telegraphMessage(self, msg, chID=None, state=None):
        if msg == 'update':
            self.channels[chID].updateState(state)
        elif msg == 'reconnect':
            self.connect()