Пример #1
0
class Motor(object):
    def __init__(self, name='SOL1B_M1'):
        if name not in mtc.MOTORS.keys():
            raise ValueError('You have not specified a valid motor')
        motor_dict = mtc.MOTORS[name]
        self._name = name
        self._set = PV(motor_dict['set'])
        self._rbv = PV(motor_dict['rbv'])
        self._status = PV(motor_dict['status'])
        self._status_vars = self._status.get_ctrlvars()
        self._logger = logger.custom_logger(__name__)

    @property
    def name(self):
        return self._name

    @property
    def pos_set(self):
        return self._set.get()

    @pos_set.setter
    def pos_set(self, val):
        if not isinstance(val, int) or isinstance(val, float):
            self._logger('position must be int or float')
            return

        self._set.put(val)

    @property
    def pos_rbv(self):
        return self._rbv.get()

    @property
    def status_vars(self):
        return self._status_vars
Пример #2
0
 def test_DoubleVal(self):
     pvn = pvnames.double_pv
     pv = PV(pvn)
     pv.get()
     cdict = pv.get_ctrlvars()
     write('Testing CTRL Values for a Double (%s)\n' % (pvn))
     self.failUnless('severity' in cdict)
     self.failUnless(len(pv.host) > 1)
     self.assertEqual(pv.count, 1)
     self.assertEqual(pv.precision, pvnames.double_pv_prec)
     units = ca.BYTES2STR(pv.units)
     self.assertEqual(units, pvnames.double_pv_units)
     self.failUnless(pv.access.startswith('read'))
Пример #3
0
 def test_DoubleVal(self):
     pvn = pvnames.double_pv
     pv = PV(pvn)
     pv.get()
     cdict  = pv.get_ctrlvars()
     write( 'Testing CTRL Values for a Double (%s)\n'   % (pvn))
     self.failUnless('severity' in cdict)
     self.failUnless(len(pv.host) > 1)
     self.assertEqual(pv.count,1)
     self.assertEqual(pv.precision, pvnames.double_pv_prec)
     units= ca.BYTES2STR(pv.units)
     self.assertEqual(units, pvnames.double_pv_units)
     self.failUnless(pv.access.startswith('read'))
Пример #4
0
class StopperCon(object):
    def __init__(self, stopper='AOM'):
        if stopper not in sc.STOPPERS.keys():
            raise ValueError('{0} is not a recognized stopper'.format(stopper))
        stopper_dict = sc.STOPPERS[stopper]
        self._stopper = stopper
        self._ctrl_pv = PV(stopper_dict['ctrl'])
        self._closed = stopper_dict['closed']
        self._opened = stopper_dict['open']
        self._ctrl_vars = self._ctrl_pv.get_ctrlvars()['enum_strs']
        self._ctrl_pv.add_callback(self._ctrl_clbk, index=0)
        self._logger = logger.custom_logger(__name__)

    @property
    def enabled(self):
        """Get enabled state"""
        return self._ctrl_pv.get()

    @enabled.setter
    def enabled(self, val):
        """Set enabled state, unfortunately they're disabeld and allowed"""
        if val not in self._ctrl_vars:
            self._logger.info('You must provide a value that is in {0}'.format(
                self._ctrl_vars))
            return

        state = self._ctrl_pv.get()

        if val and state == self._closed:
            self._logger.info('The stopper is already closed')
            return

        if val and state == self._opened:
            self._logger.info('The stopper is alaredy opened')
            return

        self._ctrl_pv.put(val)

    def _ctrl_clbk(self, pv_name=None, value=None, char_value=None, **kw):
        """Default callback to announce stopper change status"""
        self._logger.info('Stopper {0} is now {1}'.format(
            self._stopper, self._ctrl_vars[value]))
Пример #5
0
class Magnet(object):
    """Magnet control"""
    def __init__(self, name='SOL1B'):
        if name not in mc.MAGNETS.keys():
            raise ValueError('You have not specified a valid magnet')
        mag_dict = mc.MAGNETS[name]
        self._name = name
        self._bctrl = PV(mag_dict['bctrl'])
        self._bact = PV(mag_dict['bact'])
        self._bdes = PV(mag_dict['bdes'])
        self._bcon = PV(mag_dict['bcon'])
        self._ctrl = PV(mag_dict['ctrl'])
        self._tol = mag_dict['tol']
        self._length = mag_dict['length']
        self._ctrl_vars = self._ctrl.get_ctrlvars()['enum_strs']
        self._pv_attrs = self.find_pv_attrs()

    def check_state(f):
        """Decorator to only allow transitions in 'Ready' state"""
        def decorated(self, *args, **kwargs):
            if self.ctrl_value != 'Ready':
                print('Unable to perform action, magnet not in Ready state')
                return
            return f(self, *args, **kwargs)
        return decorated

    @property
    def name(self):
        """Get the magnet name"""
        return self._name

    @property
    def bctrl(self):
        """Get BCTRL value"""
        return self._bctrl.get()

    @bctrl.setter
    @check_state
    def bctrl(self, val):
        """Set bctrl value"""
        if not isinstance(val, float) or isinstance(val, int):
            print('you need to provide an in or float')
            return

        self._bctrl.put(val)

    @property
    def bact(self):
        """Get the BACT value"""
        return self._bact.get()

    @property
    def bdes(self):
        """Get BDES value"""
        return self._bdes.get()

    @property
    def ctrl_value(self):
        """Get the current action on magnet"""
        return self._ctrl_vars[self._ctrl.get()]

    @property
    def length(self):
        """Magnetic Length, should be from model"""
        return self._length

    @length.setter
    def length(self, length):
        """Set the magnetic length for a magnet"""
        if not isinstance(length, float):
            print('You must provide a float for magnet length')
            return

        self._length = length

    @property
    def pv_props(self):
        """All the properties that are PV objects/can have callbacks"""
        return self._pv_props

    @property
    def tol(self):
        return self._tol

    @tol.setter
    def tol(self, tol):
        """Set the magnetic length for a magnet"""
        if not isinstance(tol, float):
            print('You must provide a float for magnet tol')
            return False

        self._tol = tol

    @check_state
    def trim(self):
        """Issue trim command"""
        self._ctrl.put(mc.CTRL.index('TRIM'))

    @check_state
    def perturb(self):
        """Issue perturb command"""
        self._ctrl.put(mc.CTRL.index('PERTURB'))

    def con_to_des(self):
        """Issue con to des commands"""
        self._ctrl.put(mc.CTRL.index('BCOM_TO_BDES'))

    def save_bdes(self):
        """Save BDES"""
        self._ctrl.put(mc.CTRL.index('SAVE_BDES'))

    def load_bdes(self):
        """Load BDES"""
        self._ctrl.put(mc.CTRL.index('LOAD_BDES'))

    def undo_bdes(self):
        """Save BDES"""
        self._ctrl.put(mc.CTRL.index('UNDO_BDES'))

    @check_state 
    def dac_zero(self):
        """DAC zero magnet"""
        self._ctrl.put(mc.CTRL.index('DAC_ZERO'))

    @check_state
    def calibrate(self):
        """Calibrate magnet"""
        self._ctrl.put(mc.CTRL.index('CALIB'))

    @check_state
    def standardize(self):
        """Standardize magnet"""
        self._ctrl.put(mc.CTRL.index('STDZ'))

    def reset(self):
        """Reset magnet"""
        self._ctrl.put(mc.CTRL.index('RESET'))

    def find_pv_attrs(self):
        """Get all the PV object attributes"""
        pv_attrs = []
        for mem in getmembers(self):
            if len(mem) > 1 and isinstance(mem[1], PV):
                pv_attrs.append(mem[0])

        return pv_attrs

    ################## Actions #################

    def add_clbk(self, fn, attr='_bact'):
        """Add a callback function to a given attribute"""
        if attr not in self._pv_attrs:
            print('this attribute is not a pv object, ignored')
            return

        fns = [val[0] for val in getattr(self, attr).callbacks.values()]

        if fn in fns:
            print('this is a duplicate callback assignment, ignored')
            return

        print('adding callback {0}'.format(fn))
        getattr(self, attr).add_callback(fn, with_ctrlvars=False)

    def remove_clbk(self, fn, attr='_bact'):
        """Add a callback function to a given attribute"""
        if attr not in self._pv_attrs:
            print('this attribute is not a pv object, ignored')
            return

        index = None
        for k, v in getattr(self, attr).callbacks.items():
            if v[0] == fn:
                index = k

        if not index:
            print('function not found in callbacks, ignored')
            return

        print('remvong callback {0}'.format(fn))
        getattr(self, attr).remove_callback(index=index)
Пример #6
0
class ProfMon(object):
    """Generic Profile Monitor Object Class that references profile monitor MAD name"""
    def __init__(self, prof_name='OTR02'):
        if prof_name not in pc.PROFS.keys():
            raise ValueError('You have not specified a valid profile monitor')
        prof_dict = pc.PROFS[prof_name]
        self._prof_name = prof_name
        self._prof_set = PV(prof_dict['set'])
        self._prof_get = PV(prof_dict['get'])
        self._prof_image = PV(prof_dict['image'])
        self._prof_res = PV(prof_dict['res'])
        self._x_size = PV(prof_dict['xsize'])
        self._y_size = PV(prof_dict['ysize'])
        self._rate = PV(prof_dict['rate'])
        self._images = []
        self._data_thread = None
        self._gathering_data = False
        self._get_vars = self._prof_get.get_ctrlvars()['enum_strs']
        self._set_vars = self._prof_set.get_ctrlvars()['enum_strs']
        self._motion_state = self._get_vars[self._prof_get.get()]
        self._prof_get.add_callback(self._state_clbk, index=1)
        self._insert_clbk = None
        self._extract_clbk = None

    def _state_clbk(self, pvName=None, value=None, char_value=None, **kw):
        """Keep track of position/motion state"""
        self._motion_state = self._get_vars[value]

    @property
    def prof_name(self):
        """Get the profile monitor MAD name"""
        return self._prof_name

    @property
    def cur_image(self):
        """Get the current image array"""
        return self._prof_image.get()

    @property
    def saved_images(self):
        """Get the images collected"""
        return self._images

    @property
    def resolution(self):
        """Get the resolution"""
        return self._prof_res.get()

    @property
    def arr_dims(self):
        """Get the x and y dimensions"""
        return (self._x_size.get(), self._y_size.get())

    @property
    def rate(self):
        """Get the current rate"""
        return self._rate.get()

    @property
    def motion_state(self):
        """Get the current motion state of the profile monitor"""
        return self._motion_state

    @property
    def state(self):
        """Get the overall state of the profile monitor"""
        return self.__dict__

    def insert(self, user_clbk=None):
        """Generic call to insert profile monitor, can specify callback to be run"""
        if self._motion_state == pc.IN:
            print('{0}: {1}'.format(self._prof_name, pc.ALREADY_INSERTED))
            return

        if user_clbk:
            self._insert_clbk = user_clbk

        self._prof_get.add_callback(self._inserted, index=0)
        self._prof_set.put(pc.IN)

    def _inserted(self, pv_name=None, value=None, char_value=None, **kw):
        """Generic callback after profile monitor has been inserted, default"""
        if self._get_vars[value] == pc.IN:
            print('{0}: {1}'.format(self._prof_name, pc.INSERTED))

            if self._insert_clbk:
                self._insert_clbk()
                self._insert_clbk = None

            self._prof_get.remove_callback(index=0)

    def extract(self, usr_clbk=None):
        """Extract profile monitor command, can specify callback to be run"""
        if self._motion_state == pc.OUT:
            print('{0}: {1}'.format(self._prof_name, pc.ALREADY_EXTRACTED))
            return

        if user_clbk:
            self._extract_clbk = user_clbk

        self._prof_get.add_callback(self._extracted, index=0)
        self._prof_set.put(pc.OUT)

    def _extracted(self, pv_name=None, value=None, char_value=None, **kw):
        """Generic Callback for profile monitor that has been extracted, default"""
        if self._get_vars[value] == pc.OUT:
            print('{0}: {1}'.format(self._prof_name, pc.EXTRACTED))

            if self._extract_clbk:
                self._extract_clbk()
                self._extract_clbk = None

            self._prof_get.remove_callback(index=0)

    def acquire_images(self, images=1):
        """Start the thread"""
        self._data_thread = Thread(target=self._collect_image_data,
                                   args=(images, ))
        self._data_thread.start()

    def _collect_image_data(self, images, callback):
        """Threaded data collection"""
        self._gathering_data = True
        delay = 1.0 / self._rate.get()  # Rate must be in Hz
        i = 0
        while i < images:
            image = self._prof_image.get()
            if len(self._images) > 0 and array_equal(image, self._images[-1]):
                sleep(0.01)
            else:
                self._images.append(image)
                sleep(delay)
                i += 1
        if callback:  # Would want this to be pyqtSignal or Event notification type thing
            callback()
        self._gathering_data = False
        return  # No join, waste of a function
Пример #7
0
class LampCon(object):
    """Lamp Control for lcls"""
    def __init__(self, lamp_dict):  # I hate using dicts as default data structures, but...
        self._channel = PV(lamp_dict['channel'])
        self._t_enable = PV(lamp_dict['t_enable'])
        self._t_dim = PV(lamp_dict['t_dim'])
        self._t_bright = PV(lamp_dict['t_bright'])
        self._g_enable = PV(lamp_dict['g_enable'])
        self._g_dim = PV(lamp_dict['g_dim'])
        self._g_bright = PV(lamp_dict['g_bright'])
        self._lamp_name = lamp_dict['name']
        self._channel_vars = self._channel.get_ctrlvars()['enum_strs']
        self._g_lamp_vars = self._g_enable.get_ctrlvars()['enum_strs']
        self._t_lamp_vars = self._t_enable.get_ctrlvars()['enum_strs']
        self._logger = logger.custom_logger(__name__)
        
    @property
    def lamp_name(self):
        """Get generic lamp name"""
        return self._lamp_name

    @property
    def channel(self):
        """Get current lamp channel (profile monitor)"""
        return self._channel_vars[self._channel.get()]
    
    @channel.setter
    def channel(self, val):
        """Set lamp channel"""
        if val not in self._channel_vars:
            self._logger.info('Profile Monitor {0}, not available channel for lamp {1}' \
                  .format(val, self._lamp_name))
            return

        self._logger.info('Setting lamp {0} channel to {1}'.format(self._lamp_name, val))
        self._channel.put(val)

    @property
    def channels(self):
        """Get list of available channels"""
        return self._channel_vars 

    @property
    def t_lamp_enable(self):
        """Get t lamp enable status"""
        return self._t_lamp_vars[self._t_enable.get()]

    @t_lamp_enable.setter
    def t_lamp_enable(self, val):
        """Set the T Lamp to enabled/disabled"""
        state = self._t_lamp_vars[self._t_enable.get()]
        
        if state == val == pc.ENABLE:
            self._logger.info('{0}: T Lamp Already Enabled'.format(self._lamp_name))
            return

        if state == val == pc.DISABLE:
            self._logger.info('{0}: T Lamp Already Disabled'.format(self._lamp_name))
            return 

        self._t_enable.put(val)
        self._logger.info('T Lamp now {0}'.format(val)) 

    @property
    def g_lamp_enable(self):
        """Get g lamp enabled status"""
        return self._g_lamp_vars[self._g_enable.get()]

    @g_lamp_enable.setter
    def g_lamp_enable(self, val):
        """Set the G Lamp to enabled/disabled"""
        state = self._g_lamp_vars[self._g_enable.get()]

        if state == val == pc.ENABLE:
            self._logger.info('{0}: G Lamp Already Enabled'.format(self._lamp_name))
            return

        if state == val == pc.DISABLE:
            self._logger.info('{0}: G Lamp Already Disabled'.format(self._lamp_name))
            return 

        self._g_enable.put(val)
        self._logger.info('G Lamp now {0}'.format(val))
Пример #8
0
class LampCon2(object):
    """Lamp Control for lcls2 lamp"""
    def __init__(self, lamp_dict):
        self._lamp_power = PV(lamp_dict['lamp_power'])
        self._power_vars = self._lamp_power.get_ctrlvars()['enum_strs']
        self._bright_pv = PV(lamp_dict['lamp_brightness'])
        self._bright_vars = self._bright_pv.get_ctrlvars()
        self._bright_upper = self._bright_vars[pc.HI]
        self._bright_lower = self._bright_vars[pc.LO]
        self._lamp_name = lamp_dict['name']
        self._logger = logger.custom_logger(__name__)
    
    @property
    def lamp_name(self):
        """Generic name for lamp"""
        return self._lamp_name

    @property
    def brightness(self):
        """Get the current setting for the brightness"""
        return self._bright_pv.get()

    @brightness.setter
    def brightness(self, val):
        if not self._bright_lower < val < self._bright_upper:
            self._logger.info('{0} is not in range'.format(val))
            return
            
        self._bright_pv.put(val)

    @property
    def bright_up_lim(self):
        """Get the upper limit for the brightness"""
        return self._bright_upper

    @property
    def bright_lo_lim(self):
        """Get the lower limit for the brightness"""
        return self._bright_lower

    @property
    def lamp_power(self):
        """Get the on/off state for the lamp"""
        return self._power_vars[self._lamp_power.get()]

    @lamp_power.setter
    def lamp_power(self, val):
        """Power On/Off setter.  Val must be 'On' or 'Off'"""
        if val not in self._power_vars:
            self._logger.info('You must provide a value that is "On" or "Off"')
            return

        state = self._power_vars[self._lamp_power.get()]

        if val == state == pc.ON:
            self._logger.info("The lamp is already on")
            return

        if val == state == pc.OFF:
            self._logger.info("The lamp is already off")
            return
        
        self._logger.info('Turning lamp {0}'.format(val))
        self._lamp_power.put(val)

    @property
    def state(self):
        """Get the current state of the object class"""
        return self.__dict__

    def dim_lamp(self, step=pc.LAMP_STEP, callback_fn=None):
        """Dim lamp by a step"""
        new_val = self._bright_pv.get() - step

        if new_val < self._bright_lower:
            self._logger.info('You can not dim any further')
            return

        self._bright_pv.put(new_val)
        
    def brighten_lamp(self, step=pc.LAMP_STEP, callback=None):
        """Brighten the lamp"""
        new_val = self._bright_pv.get() + step

        if new_val > self._bright_upper:
            self._logger.info('You can not brighten any further')
            return
        
        self._bright_pv.put(new_val)