示例#1
0
    def create(self):
        """Create :py:mod:`rts2saf.devices.CCD` based on properties stored in configuration. Optionally fetch filter offsets from CCD and/or  check if device is present. 

        :return:  :py:mod:`rts2saf.devices.CCD` if success else None

        """
        # configuration has been read in, now create objects
        # create object CCD

        self.ccd= CCD( 
            debug        =self.debug,
            name         =self.rt.cfg['CCD_NAME'],
            ftws         =self.ftws,
            binning      =self.rt.cfg['CCD_BINNING'],
            window       =self.rt.cfg['WINDOW'],
            pixelSize    =float(self.rt.cfg['PIXELSIZE']),
            baseExposure =float(self.rt.cfg['BASE_EXPOSURE']),
            logger=self.logger
            )
            
        if self.check:
            if not self.ccd.check(proxy=self.proxy):
                return None
        if self.fetchOffsets:
            # fetch the filter offsets
            if not self.filterOffsets():
                return None

        return self.ccd
示例#2
0
 def test_deviceClasses(self):
     logger.info('== {} =='.format(self._testMethodName))
     # they are harmless
     # ToDo: move write from CheckDevices to these classes
     ft = Filter()
     self.assertIs(type(ft), Filter,
                   'no object of type: '.format(type(Filter)))
     ftw = FilterWheel()
     self.assertIs(type(ftw), FilterWheel,
                   'no object of type: '.format(type(FilterWheel)))
     foc = Focuser()
     self.assertIs(type(foc), Focuser,
                   'no object of type: '.format(type(Focuser)))
     ccd = CCD()
     self.assertIs(type(ccd), CCD, 'no object of type: '.format(type(CCD)))
示例#3
0
class CreateCCD(CreateDevice):
    """Create device :py:mod:`rts2saf.devices.CCD`

    :var debug: enable more debug output with --debug and --level
    :var check: if True check presence of device
    :var proxy: :py:mod:`rts2.proxy`
    :var verbose: True, more debug output
    :var rt: run time configuration,  :py:mod:`rts2saf.config.Configuration`, usually read from /usr/local/etc/rts2/rts2saf/rts2saf.cfg
    :var logger:  :py:mod:`rts2saf.log`
    :var ftws: list of  :py:mod:`rts2saf.devices.FilterWheel`
    :var fetchOffsets: if True call `filterOffsets`
    """    
    def __init__( self, ftws=None, fetchOffsets=False, *args, **kw ):
        super( CreateCCD, self ).__init__( *args, **kw )
        self.ftws=ftws
        self.fetchOffsets=fetchOffsets
        self.ccd=None

    def create(self):
        """Create :py:mod:`rts2saf.devices.CCD` based on properties stored in configuration. Optionally fetch filter offsets from CCD and/or  check if device is present. 

        :return:  :py:mod:`rts2saf.devices.CCD` if success else None

        """
        # configuration has been read in, now create objects
        # create object CCD

        self.ccd= CCD( 
            debug        =self.debug,
            name         =self.rt.cfg['CCD_NAME'],
            ftws         =self.ftws,
            binning      =self.rt.cfg['CCD_BINNING'],
            window       =self.rt.cfg['WINDOW'],
            pixelSize    =float(self.rt.cfg['PIXELSIZE']),
            baseExposure =float(self.rt.cfg['BASE_EXPOSURE']),
            logger=self.logger
            )
            
        if self.check:
            if not self.ccd.check(proxy=self.proxy):
                return None
        if self.fetchOffsets:
            # fetch the filter offsets
            if not self.filterOffsets():
                return None

        return self.ccd

    # ToDo
    # interestingly on can set filter offsets for
    # filter_offsets_B
    # filter_offsets_C
    # but there is no way to specify it via cmd line
    # or --offsets-file
    #
    # filter_offsets_A, etc. see Bootes-2 device andor3
    # ftos=self.proxy.getValue(self.ccd.name, 'filter_offsets_B')
    # print ftos
    # self.proxy.setValue(self.ccd.name,'filter_offsets_B', '6 7 8')
    # self.proxy.refresh()
    # ftos=self.proxy.getValue(self.ccd.name, 'filter_offsets_B')
    # print ftos
    # ftos=self.proxy.getValue(self.ccd.name, 'filter_offsets_C')
    # print ftos
    # self.proxy.setValue(self.ccd.name,'filter_offsets_C', '16 17 18')
    # self.proxy.refresh()
    # ftos=self.proxy.getValue(self.ccd.name, 'filter_offsets_C')
    # print ftos
    # sys.exit(1)
        

    # Workaround for the above
    # Device camd provides the following variables
    # in case multiple filter wheels are present.
    # This example shows the configuration of Bootes-2:
    #
    # CCD andor3
    # FLI FTWs: COLWFLT, COLWSLT, COLWGRS
    # Variables appearing in tab andor3
    #  variable   ftw name   filters (read out from device, e.g. COLWGRS)
    #  wheel      COLWFLT  
    #  wheelA     COLWFLT    open, R, g, r, i, z, Y, empty8
    #  wheelB     COLWSLT    closed, slit1, slit2, slit3, slit4, h.., p.., open
    #  wheelC     COLWGRS    open, grism1, empty3, empty4, empty5, empty6, empty7, empty8 
    # 
    # Filters on wheels  wheelB, wheelC etc. which are 
    # named open or empty are treated as empty slots.
    # Only the filter wheel appearing in camd::wheel 
    # is used.
    # During a focus run filter wheels wheelB, wheelC etc. are
    # set to a slot named open or empty*


    def filterOffsets(self, proxy=None):
        """Fetch for all filter wheels their filter offsets and check if all configured items are present in RTS2 run time environment.

        :return: True if success else False

        """
        fts=dict()  # filters
        ftos=dict() # filter offsets
        ccdFtwn=collections.defaultdict(str)
        # as of 2013-11017 CCD::filter_offsets_X are not filled
        for i, ftw in enumerate(self.ftws):
            if i:
                # FILTB, FILTC, ...
                ext= chr( 65 + i) # 'A' + i, as it is done in camd.cpp
                ccdN ='wheel{0}'.format(ext)
                ftwn=self.proxy.getValue(self.ccd.name, ccdN)
                ccdFtwn[ftwn] = ccdN 
                fts[ftwn] =self.proxy.getSelection(self.ccd.name, 'FILT{0}'.format(ext))
                ftos[ftwn]=self.proxy.getValue(self.ccd.name, 'filter_offsets_{0}'.format(ext))
            else:
                ccdN ='wheel'
                ftwn=self.proxy.getValue(self.ccd.name, ccdN)
                ccdFtwn[ftwn] =  ccdN
                fts[ftwn] =self.proxy.getSelection(self.ccd.name, 'filter')
                ftos[ftwn]=self.proxy.getValue(self.ccd.name, 'filter_offsets')

        for ftw in self.ftws: # defined in configuration
            ftIUns= [x.name for x in  ftw.filters] # filters from configuration
            try:
                ftw.ccdName=ccdFtwn[ftw.name] # these filter wheels names  are read back from CCD
                if self.debug: self.logger.debug('filterOffsets: found filter wheel: {0}, named on CCD: {1}'.format(ftw.name, ftw.ccdName))
            except Exception, e:
                self.logger.error('filterOffsets: {0} {1} configured filter wheel not found, error: {2}'.format(self.ccd.name,ftw.name, e))
                return False

            if len(ftos[ftw.name])==0:
                self.logger.warn('filterOffsets: {0}, {1} no filter offsets could be read from CCD, but filter wheel/filters are present'.format(self.ccd.name, ftw.name))

            if len(fts[ftw.name])==0:
                self.logger.warn('filterOffsets: {0}, {1} no filters could be read from CCD, but filter wheel/filters are present'.format(self.ccd.name, ftw.name))
            else:
                self.logger.info('filterOffsets: {0}, filter wheel {1} defined filters {2}'.format(self.ccd.name, ftw.name, [x for x in fts[ftw.name]]))
                self.logger.info('filterOffsets: {0}, filter wheel {1} used    filters {2}'.format(self.ccd.name, ftw.name, ftIUns))

            ccdOffsets = [ x for x in ftos[ftw.name]] # offsets from CCD
            ccdFilters = [ x for x in fts[ftw.name]]  # filter names from CCD

            for k, ft in enumerate(ftw.filters): # defined in configuration 
                if ft.name in ccdFilters:            
                    for nm in self.rt.cfg['EMPTY_SLOT_NAMES']:
                        # e.g. filter name R must exactly match!
                        p = re.compile(nm)
                        m = p.match(ft.name)
                        if m:
                            ft.OffsetToEmptySlot= 0
                            if self.debug: self.logger.debug('filterOffsets: {0}, {1} offset set to ZERO'.format(ftw.name, ft.name))
                            break
                    else:
                        try:
                            ft.OffsetToEmptySlot= ccdOffsets[k]
                            if self.debug: self.logger.debug('filterOffsets: {0}, {1} offset {2} from ccd: {3}'.format(ftw.name, ft.name, ft.OffsetToEmptySlot,self.ccd.name))
                        except Exception, e:
                            ft.OffsetToEmptySlot= 0
                            self.logger.warn('filterOffsets: {0}, {1} NO offset from ccd: {2}, setting it to ZERO, error: {3}'.format(ftw.name, ft.name,self.ccd.name, e))
                else:
                    self.logger.warn('filterOffsets: {0} filter {1} not found on CCD {2}, ignoring it'.format( ftw.name, ft.name, self.ccd.name))