示例#1
0
 def dwell(self, c, dwell=None):
     '''Set/query the dwell trigger.
     
     Input:
     dwell - Time in seconds if internal dwell timer used
           - Voltage threshold of external advance signal used
           
     Returns:
     (type, parameter) - Type is 'Internal' or 'External' with
                         associated dwell time/threshold
     '''
     if dwell is not None:
         if dwell.isCompatible('s'):
             if dwell['s'] < jobs.DWELL_MIN or dwell['s'] > jobs.DWELL_MAX:
                 string = 'Dwell time must be between %f and %f seconds' %\
                          (jobs.DWELL_MIN, jobs.DWELL_MAX)
                 raise Error(string)
         else:
             if dwell['V'] < jobs.DISC_MIN or dwell['V'] > jobs.DISC_MAX:
                 string = 'Dwell trigger threshold must be between %f and %f volts' %\
                          (jobs.DISC_MIN, jobs.DISC_MAX)
                 raise Error(string)
                 
         self.params['Dwell'] = (dwell.isCompatible('s'), dwell)
     
     isInt, value = self.params['Dwell']
     string = 'Internal' if isInt else 'External'
     return (string, value)
示例#2
0
 def scan_range(self, c, start=None, startPartial=0, stop=None, stopPartial=0):
     if start is not None:
         if stop is None:
             raise Error('Must provide stop position')
         elif stop < start or ((start == stop) and (startPartial > stopPartial)):
             raise Error('Stop position must be after start')
             
         self.params['Scan Range'] = ((start, startPartial), (stop, stopPartial))
     return self.params['Scan Range']
示例#3
0
    def scan_range(self, c, start=None, stop=None):
        '''
        Set/query scan channel range.
        
        Input:
            start - Channel to start scan at. Can be integer identifying start
                    channel or a tuple (channel, partial) for partial channel increment.
                    
            stop -  Channel to stop at. Same format as start channel.
        Returns:
            [start, stop] - Scan pass bounds as a tuple. Both channels are returned
                            as tuple elements (channel, partial) where partial
                            indicates 8ths of a channel. (ie. partial=5 is 5/8 of
                            a channel)
        '''

        if start is not None:
            if stop is None:
                raise Error('Must inclide stop channel.')
            elif (not isValidCh(start)) or (not isValidCh(stop)):
                raise InvalidPositionError()

            if type(start) is not tuple:
                start = (start, 0)
            if type(stop) is not tuple:
                stop = (stop, 0)

            self.range = (start, stop)

        return self.range
示例#4
0
    def position(self, c, channel=None, partial=0, direction=True):
        '''Get or set the current stepper position.
        Input:
        channel - The current channel position
        partial - Channel fraction (8 steps per channel)
        direction - Either 'forward' or 'backward' or
                    True/False for forward and backward
        Returns:
        Current position and direction as a tuple with
        direction as a string
        (channel, partial, direction)
        '''
        if channel is not None:
            #if we're setting the channel by string, validate and set
            #boolean value as forward/backward (true/false)
            if type(direction) is str:
                d = direction.lower()
                if d not in DIR_MAP.keys():
                    raise Error('Direction must be Forward or Backward')
                dval = d == 'forward'
            else:
                dval = direction

            if not calc.isValidCh((channel, partial)):
                raise InvalidPosition()

            self.posn = (channel, partial, dval)

        c, f, d = self.posn
        dStr = 'Forward' if d else 'Backward'
        return (c, f, dStr)
示例#5
0
 def stop(self, c):
     running = yield self._isRunning()
     if not running:
         raise Error('Scan is not running')
     
     p = self.pulser.packet()
     p.removeListener(self._scanCallback, ID = self.ID)
     p.stop()
     yield p.send()
示例#6
0
    def scan_range(self, c, start=None, end=None):
        #ensure if there's a scan start there's an end
        if start is not None:
            if end is None:
                raise Error('No scan end position')

        #store possible new positions and retrieve
        sPos = self.position(c, start)
        ePos = self.move_to(c, end)
        return (sPos, ePos)
示例#7
0
 def discriminator_level(self, c, level=None):
     '''Set/query current discriminator voltage'''
     if level is not None:
         if level['V'] < jobs.DISC_MIN or level['V'] > jobs.DISC_MAX:
             string = 'Discriminator level must be between %f and %f'\
                      % (jobs.DISC_MIN, jobs.DISC_MAX)
             raise Error(string)
         self.params['DiscLevel'] = level
         
     return self.params['DiscLevel']
示例#8
0
 def sweeps(self, c, passes=None):
     '''Set/query the number of scan sweeps. (None queries)'''
     if passes is not None:
         if passes < jobs.PASS_MIN or passes > jobs.PASS_MAX:
             string = 'Pass count must be between %d and %d'\
                      % (jobs.PASS_MIN, jobs.PASS_MAX)
             raise Error(string)
             
         self.params['Passes'] = passes
         
     return self.params['Passes']
示例#9
0
 def pass_length(self, c, length=None):
     '''Set/query the number of bins in the scan pass. (None queries)'''
     if length is not None:
         if length < jobs.LEN_MIN or length > jobs.LEN_MAX:
             string = 'Pass length must be between %d and %d' %\
                      (jobs.LEN_MIN, jobs.LEN_MAX)
             raise Error(string)
             
         self.params['Length'] = length   
         
     return self.params['Length']
    def open(self, c, port=''):
        """Opens a serial port in the current context.

        args:
        port   device name as returned by list_serial_ports.

        On windows, the device name will generally be of the form
        COM1 or COM42 (i.e., without the device prefix \\\\.\\).  On
        linux, it will be the device node name (ttyUSB0) without the
        /dev/ prefix.  This is case insensitive on windows, case sensitive
        on Linux.  For compatibility, always use the same case.
        """
        c['Timeout'] = 0
        if 'PortObject' in c:
            c['PortObject'].close()
            del c['PortObject']
        if not port:
            for i in range(len(self.SerialPorts)):
                try:
                    c['PortObject'] = Serial(self.SerialPorts[i].devicepath,
                                             timeout=0)
                    break
                except SerialException:
                    pass
            if 'PortObject' not in c:
                raise NoPortsAvailableError()
        else:
            for x in self.SerialPorts:
                if os.path.normcase(x.name) == os.path.normcase(port):
                    try:
                        c['PortObject'] = Serial(x.devicepath, timeout=0)
                        return x.name
                    except SerialException as e:
                        message = str(e)
                        if message.find('cannot find') >= 0:
                            raise Error(code=1, msg=message)
                        else:
                            raise Error(code=2, msg=message)
        raise Error(code=1, msg='Unknown port %s' % (port,))
示例#11
0
 def open(self, c, port=0):
     """Opens a serial port in the current context."""
     c['Timeout'] = 0
     if 'PortObject' in c:
         c['PortObject'].close()
         del c['PortObject']
     if port == 0:
         for i in range(len(self.SerialPorts)):
             try:
                 c['PortObject'] = Serial(self.SerialPorts[i], timeout=0)
                 break
             except SerialException:
                 pass
         if 'PortObject' not in c:
             raise NoPortsAvailableError()
     else:
         try:
             c['PortObject'] = Serial(port, timeout=0)
         except SerialException, e:
             if e.message.find('cannot find') >= 0:
                 raise Error(code=1, msg=e.message)
             else:
                 raise Error(code=2, msg=e.message)
示例#12
0
    def passes(self, c, passes=None):
        '''
        Set/query number of scan passes.
        
        Input:
            passes - Number of sweeps to make over the scan range
        Returns
            Number of passes
        '''

        if passes is not None:
            if passes < 1:
                raise Error('Invalid pass number')
            self.passes = passes
        return self.passes
示例#13
0
    def dwell_time(self, c, dwell=None):
        '''
        Set/query the dwell time per MCS bin.
        Input:
            dwell - Dwell time in seconds per MCS bin. None for query
        Returns:
            Current dwell time per bin in seconds.
        '''

        if dwell is not None:
            if dwell <= MIN_DWELL:
                raise Error('Dwell time must be at least %f' % MIN_DWELL['s'])
            self.dwell = dwell

        return self.dwell
示例#14
0
    def changeMonitor(self, channel, command, keys=None):
        settings = BUS_SETTINGS[channel]

        if keys is None:
            keys = sorted(settings.keys())

        if command is None:
            returnValue(keys)

        if command not in settings:
            raise Error('Allowed commands: {}.'.format(', '.join(keys)))

        self.rackMonitor.updateBus(channel, self.activeCard, command)
        change = yield self.sendMonitorPacket(command, settings)
        returnValue(change)
示例#15
0
 def startProcessing(self):
     #self.cumulRawData = np.array()
     #self.cumulProcData = np.array()
     try:
         yield self.readhandle.call('cd', self.inputpath)
         yield self.readhandle.call('open', self.inputdataset)
         yield self.writehandle.call('cd', *(self.outputpath, True))
     except:
         raise Error('Dataset not found in provided directory'
                     )  #find a way to get this out to the user
     #start a timer 24 hours
     #connect endprocessing
     if self.followlive:
         yield self.processRepeatedly()
     else:
         yield self.processOnce()
示例#16
0
 def start(self, c):
     running = yield self._isRunning()
     if running:
         raise Error('A scan is currently in progress')
         
     #move stepper into position and wait until complete
     ch, frac = self.params['Scan Range'][0]
     yield self.stepper.move_to(ch, frac, True)
     yield self._waitForStepper()
         
     #now prepare for scan pass
     self.currentPass = 0
     yield self._prepPulser()
     yield self._prepMCS()
     yield self._scanPass()  
     
     self.onScanStart(self.params['Passes'])
示例#17
0
    def channel_ratio(self, c, ratio=None):
        '''
        Set/query current channel ratio. Defines the number of
        stepper channels per MCS bin. Minimum must be 1/8 or 0.125.
        
        Input:
            ratio - Ratio to set. None if querying.
        Returns:
            Current ratio as floating point number
        '''
        if ratio is not None:
            if ratio < MIN_RATIO:
                raise Error('Channel ratio must be at least %f' % MIN_RATIO)

            #round to nearest increment
            ratio -= (ratio % MIN_RATIO)
            self.ratio = ratio
        return self.ratio
示例#18
0
 def acquisition_mode(self, c, mode = None):
     '''Set/query acquisition mode. 
     
     Input
     None : Query current setting
     Mode : Set mode to one of 'Rep', 'Sum', 'RepSum'
     
     Returns
     Currently set acquisition mode.
     '''
     if mode is not None:
         if mode not in ACQ_MODES:
             opts = ', '.join(ACQ_MODES)
             string = 'Acquisition mode must be one of %s' % opts
             raise Error(string)
         self.params['AcqMode'] = mode
         
     return self.params['AcqMode']
示例#19
0
 def processData(self,
                 c,
                 path,
                 dataset,
                 process,
                 followlive=False,
                 arguments=None):
     """
     Process the data by specifying the path and dataset name in datavault.
     If followlive is selected, any new updates to the selected dataset will be processed on the flu
     Arguements let user change the default processing settings
     """
     if process not in self.processingFunctions.availableProcesses():
         raise Error('Process not available')
     readhandle = ContextHandle(self.client, 'data_vault')
     writehandle = ContextHandle(self.client, 'data_vault')
     request = Request(path, dataset, process, readhandle, writehandle,
                       followlive, arguments)
     outputInfo = request.getOutputInfo()
     reactor.callLater(0, request.startProcessing)
     return outputInfo
示例#20
0
    def mode(self, ch, mode=None, modeParameter=None):
        if mode is not None:
            if mode not in MODE_TYPES.keys():
                raise Error('Mode type invalid.')

        tag = ':MODE' if ch == 0 else ':CMODE'
        modeVal = yield self._param(tag, mode, 'mode', ch)

        m = modeVal if mode is None else mode
        if m == 'Burst':
            param = yield self._param(':BCO', modeParameter, 'int', ch)
        elif m == 'DutyCycle':
            inP = (None, None) if modeParameter is None else modeParameter
            pco = yield self._param(':PCO', inP[0], 'int', ch)
            nco = yield self._param(':OCO', inP[1], 'int', ch)
            param = (pco, nco)
        else:
            param = 0

        if mode is None:
            returnValue((modeVal, param))
示例#21
0
 def input_impedance(self, c, imped=None):
     '''Set/query input signal impedance
     
     None : Query current setting
     True : Input at 50 Ohm impedance
     False : Input at 1 kOhm impedance
     Value can also be actual impedance value
     
     Returns : Impedance value
     '''
     if imped is not None:
         if type(imped) is bool:
             val = imped
         else:
             if imped['Ohm'] not in [50, 1000]:
                 raise Error('Impedance must be 50, 1000 Ohms or boolean')
             else:
                 val = imped['Ohm'] == 50
         
         self.params['Impedance'] = val
         
     return U.Value(50 if self.params['Impedance'] else 1000, 'Ohm')
示例#22
0
 def discriminator_edge(self, c, rising=None):
     '''Set/query input channel discriminator edge. 
     
     None queries input. Can be set with edge type
     'Rising' or 'Falling' or by
     True/False for rising/falling edge.
     
     Returns the edge type as text
     '''
     if rising is not None:
         if type(rising) is str:
             rStr = rising.lower()
             if rStr not in ['rising', 'falling']:
                 
                 rvals = ', '.join(['Rising', 'Falling'])
                 raise Error('Edge must be one of %s' % rvals)
             else:
                 rVal = rStr == 'rising'
         else:
             rVal = rising
             
         self.params['DiscEdge'] = rVal
         
     return 'Rising' if self.params['DiscEdge'] else 'Falling'
示例#23
0
class SerialServer(LabradServer):
    """Provides access to a computer's serial (COM) ports."""
    name = '%LABRADNODE% Serial Server'

    def initServer(self):
        if sys.platform.startswith('win32'):
            self.enumerate_serial_windows()
        else:
            self.enumerate_serial_pyserial()

    def enumerate_serial_windows(self):
        """Manually Enumerate the first 20 COM ports.

        pyserial includes a function to enumerate device names, but it
        possibly doesn't work right on windows for COM ports above 4.
        http://stackoverflow.com/questions/12090503/listing-available-com-ports-with-python
        """
        self.SerialPorts = []
        print 'Searching for COM ports:'
        for a in range(1, 20):
            COMexists = True
            dev_name = 'COM{}'.format(a)
            dev_path = r'\\.\{}'.format(dev_name)
            try:
                ser = Serial(dev_name)
                ser.close()
            except SerialException as e:
                if e.message.find('cannot find') >= 0:
                    COMexists = False
            if COMexists:
                self.SerialPorts.append(SerialDevice(dev_name, dev_path))
                print "  ", dev_name
        if not len(self.SerialPorts):
            print '  none'

    def enumerate_serial_pyserial(self):
        """This uses the pyserial built-in device enumeration.

        We ignore the pyserial "human readable" device name
        because that appears to make no sense.  For instance, a
        particular FTDI USB-Serial adapter shows up as 'Microsoft
        Corp. Optical Mouse 200'.

        Following the example from the above windows version, we try to open
        each port and ignore it if we can't.
        """
        dev_list = serial.tools.list_ports.comports()
        self.SerialPorts = []
        for d in dev_list:
            dev_path = d[0]
            try:
                ser = Serial(dev_path)
                ser.close()
            except SerialException as e:
                pass
            else:
                _, _, dev_name = dev_path.rpartition(os.sep)
                self.SerialPorts.append(SerialDevice(dev_name, dev_path))

    def expireContext(self, c):
        if 'PortObject' in c:
            c['PortObject'].close()

    def getPort(self, c):
        try:
            return c['PortObject']
        except:
            raise NoPortSelectedError()

    @setting(1, 'List Serial Ports', returns=['*s: List of serial ports'])
    def list_serial_ports(self, c):
        """Retrieves a list of all serial ports.

        NOTES:
        This list contains all ports installed on the computer,
        including ones that are already in use by other programs."""
        print self.SerialPorts
        port_list = [x.name for x in self.SerialPorts]

        return port_list

    @setting(
        10,
        'Open',
        port=[': Open the first available port', 's: Port to open, e.g. COM4'],
        returns=['s: Opened port'])
    def open(self, c, port=''):
        """Opens a serial port in the current context.

        args:
        port   device name as returned by list_serial_ports.

        On windows, the device name will generally be of the form
        COM1 or COM42 (i.e., without the device prefix \\\\.\\).  On
        linux, it will be the device node name (ttyUSB0) without the
        /dev/ prefix.  This is case insensitive on windows, case sensitive
        on Linux.  For compatibility, always use the same case.
        """
        c['Timeout'] = 0
        if 'PortObject' in c:
            c['PortObject'].close()
            del c['PortObject']
        if not port:
            for i in range(len(self.SerialPorts)):
                try:
                    c['PortObject'] = Serial(self.SerialPorts[i].devicepath,
                                             timeout=0)
                    break
                except SerialException:
                    pass
            if 'PortObject' not in c:
                raise NoPortsAvailableError()
        else:
            for x in self.SerialPorts:
                if os.path.normcase(x.name) == os.path.normcase(port):
                    try:
                        c['PortObject'] = Serial(x.devicepath, timeout=0)
                        return x.name
                    except SerialException, e:
                        if e.message.find('cannot find') >= 0:
                            raise Error(code=1, msg=e.message)
                        else:
                            raise Error(code=2, msg=e.message)
        raise Error(code=1, msg='Unknown port %s' % (port, ))
示例#24
0
 def optionalInputs(self, c, process):
     """Returns a list of tuples of available inputs with the default values for a given process"""
     if process not in self.processingFunctions.availableProcesses():
         raise Error('Process not available')
     return self.processingFunctions.availableInputs(process)