Beispiel #1
0
class OptimizeTab:
    def __init__(self, ui, default_yspacing=1., default_iter=10):
        print 'loading OPT'
        self.ui = ui
        self.slitlets=Slitlets()
        self.opt_yspacing = default_yspacing
        self.opt_niter = default_iter
        
    def setoptimizer_yspacing(self):
        self.opt_yspacing = self.checkyspacing_input(self.ui.lineEditOpt_Yspacing.text())
        
    def setoptimizer_iter(self):
        self.opt_niter = self.checkniter_input(self.ui.lineEditOpt_Niter.text())

    def includerefstars(self):
        if self.ui.checkBoxOpt_IncRefstars.isChecked():
            nrefstars = len(np.where(self.slitlets.data['priority'] == -1)[0])
            self.ui.lineEditOpt_AllRefstars.setText(str(nrefstars))
        else:
            self.ui.lineEditOpt_AllRefstars.setText('')

    def setnumrefstars(self):
        print self.ui.lineEditOpt_NumRefstars.text()

        
    def optimize(self): 
        """Run the optimizer program and optimize the slits"""
        msg = "Optimize the Slitlets"
        print msg
        cra = self.slitmask.center_ra
        cdec = self.slitmask.center_dec
        rotang = self.slitmask.position_angle
        equinox = 2000
        is_in_fov = np.where(self.slitlets.data['fov_flag'] == 1)[0]

        # jpk: this will need to be added in the next version
#        is_in_fov = np.where((self.slitlets.data['inmask_flag'] == 1) * (self.slitlets.data['fov_flag'] == 1))[0]

        ra = self.slitlets.data['targ_ra']
        dec = self.slitlets.data['targ_dec']
        pri = self.slitlets.data['priority']
        slen = self.slitlets.data['len1'] + self.slitlets.data['len2'] 
        swid = self.slitlets.data['width']
        stilt = self.slitlets.data['tilt']
        
        Nstars_req = 0. # **** Paul: I'm not quite sure where to get this from ****
        Niter=10 # **** as above ****
        # set all inmask flags to zero before running optimiser
        #self.slitlets.emptymask()
        
        # -- only run this on objects within FOV:        
        ok = is_in_fov
        if not ok.any(): 
           print "No objects in the field of view--update mask center and run again"
           return

        print ra[ok]
        tra = ra[ok]
        tdec = dec[ok]
        tpri = pri[ok]
        tslen = slen[ok]
        tswid = swid[ok]
        tstilt = stilt[ok]
        print 'running optimizer'
 
        tin_mask = opt.pyslit_optimize(cra, cdec, rotang, equinox, tra, tdec, \
                                    tpri,tslen,tswid,tstilt,\
                                    Niter,self.opt_yspacing, Nstars_req)
        # apply index numbers to full list:
        in_mask = ok[tin_mask]

        # reset all the in_mask values, otherwise the objects which should not
        # be in the optimized mask will still have a in_mask flag 
        self.slitlets.data['inmask_flag'] = 0
        self.slitlets.data['collision_flag'] = 0

        # now add the in_mask flag to the sources which was found by the
        # optimizer 
        for sid in in_mask:
            self.slitlets.addtomask(sid)
        self.updatetabs()


    def updatetabs(self):
        self.slitmask.outFoV_all()
        self.slitmask.find_collisions()
        self.slitlets.update_flags()
#        pass
    
    def checkyspacing_input(self, x):
        try:
            val = float(x)
            if val > 0:
                return val
            else:
                self.opt_yspacing = 1
                self.ui.lineEditOpt_Yspacing.setText(str(self.opt_yspacing))
        except ValueError,e:
            self.opt_yspacing = 1
            self.ui.lineEditOpt_Yspacing.setText(str(self.opt_yspacing))
Beispiel #2
0
class SlitMask(QObject):
    def __init__(self, center_ra=None, center_dec=None, position_angle=0, target_name='', mask_name='',
                 equinox=2000, proposal_code='', proposer='', creator='', validated=False):
        super(QObject, self).__init__();
        self.__center_ra = None
        self.__center_dec = None
        self.__position_angle = None
        self.__equinox = None
        self.add_center_ra(center_ra)
        self.add_center_dec(center_dec)
        self.add_position_angle(position_angle)
        self.add_equinox(equinox)
        
        self.target_name = target_name
        self.mask_name = mask_name
        self.proposal_code = proposal_code
        self.proposer = proposer
        self.creator = creator
        self.validated = validated

        #create the slitlets
        self.slitlets = Slitlets()

        #needed for writing xml
        self.impl = getDOMImplementation()

#        self.connect(self, SIGNAL('xmlloaded'), self.printcreator)
        
    @property
    def center_ra(self):
        return self.__center_ra
    @property
    def center_dec(self):
        return self.__center_dec
    @property
    def position_angle(self):
        return self.__position_angle
    @property
    def equinox(self):
        return self.__equinox

    def add_center_ra(self, new_center_ra):
        if new_center_ra is None: 
            self.__center_ra=None
            return
        if new_center_ra < 0 or new_center_ra >= 360:
            self.__center_ra=None
#            raise SlitMaskError()
            return
        changed = new_center_ra != self.__center_ra
        self.__center_ra = new_center_ra
        if changed:
            pass
            # send signal

    def add_center_dec(self, new_center_dec):

        if new_center_dec is None : 
            self.__center_dec=None
            return
        if new_center_dec < -90 or new_center_dec > 90:
            self.__center_dec=None
#            raise SlitMaskError()
            return
        changed = new_center_dec != self.__center_dec
        self.__center_dec = new_center_dec
        if changed:
            pass
            # send signal

    def add_position_angle(self, new_position_angle):
        """Update the value of the position angle"""
        #if None, keep as none
        if new_position_angle is None:
            self.__position_angle=None
            return
        #if a str is given, try to update to a float

        if new_position_angle < 0 or new_position_angle > 360:
            self.__position_angle=None
            return
        changed = new_position_angle != self.__position_angle
        self.__position_angle = new_position_angle
        if changed:
            pass
            # send signal

    def add_equinox(self, new_equinox):
            """Update the equinox value"""
            #if None, keep as none
            if new_equinox is None:
                self.__equinox=None
                return
            if new_equinox < 0:
                self.__equinox=None
                return
#                raise SlitMaskError()
            changed = new_equinox != self.__equinox
            self.__equinox = new_equinox
            if changed:
                pass
                # send signal

    def set_MaskPosition(self):
       """Sets the central mask position from the current slit positions.  The setting of the mask position works on the following
          priority: 1) If an object is givne with a priority of 2, that object sets the masks position.  2) If objects are
          pre-selected to be in the mask, they set the center position of the mask.  3) Set the center position to be at the 
          center of the catalog
       """
       #get the arrays that you might need
       priority = self.slitlets.data['priority']
       inmask = self.slitlets.data['inmask_flag']
       ra = self.slitlets.data['targ_ra']
       dec = self.slitlets.data['targ_dec']

       if priority.any() >= 2:
          cen_ra = ra[priority == 2].mean()
          cen_dec = dec[priority == 2].mean()
       elif inmask.any():
          cen_ra = ra[inmask == 1].mean()
          cen_dec = dec[inmask == 1].mean()
       else:
          cen_ra = ra.mean()
          cen_dec = dec.mean()
 
       self.add_center_ra(cen_ra)
       self.add_center_dec(cen_dec)
       self.add_position_angle(0)

    #
    # ... analogous methods for other properties ...
    #

    def loadxmlinfo(self,par):

        self.proposal_code = par['proposalcode']
        self.proposer = par['pi']
        self.creator = par['creator']
        self.mask_name = par['masknum']
        self.validated = par['validated']
        self.add_center_ra(float(par['centerra']))
        self.add_center_dec(float(par['centerdec']))
        self.add_position_angle(float(par['rotangle']))
        print par['centerra'], par['centerdec']
        print self.center_ra, self.center_dec
        try:
           self.target_name = par['target']
        except:
           pass

#        c = str(self.creator)
#        self.emit(SIGNAL('xmlloaded'), self.creator)
      
        
#for testing the emit and connect
#    def printcreator(self, c):
#        print 'the creator is: ', c
        
    def readmaskxml(self, dom):
        # read all the parameters into dictionaries
        parameters = dom.getElementsByTagName('parameter')

        Param = {}
        for param in parameters:
            Param[str(param.getAttribute('name')).lower()] \
            = str(param.getAttribute('value')).lower()


        # read all the reference stars into dictionaries
        Refstars = {}
        refstars = dom.getElementsByTagName('refstar')
        for refstar in refstars:
            t = {}
            t['xce'] =  float(refstar.getAttribute('xce'))
            t['yce'] =  float(refstar.getAttribute('yce'))
            t['mag'] = float(refstar.getAttribute('mag'))
            t['id'] = str(refstar.getAttribute('id'))
            Refstars[refstar.getAttribute('id')] = t

        # read all the slits into dictionaries
        Slits = {}
        slits = dom.getElementsByTagName('slit')
        for slit in slits:
            t = {}
            t['xce'] = float(slit.getAttribute('xce'))
            t['yce'] = float(slit.getAttribute('yce'))
            t['width'] = float(slit.getAttribute('width'))
            t['length'] = float(slit.getAttribute('length'))
            t['len1'] = float(slit.getAttribute('length')) / 2.
            t['len2'] = float(slit.getAttribute('length')) / 2.
            t['priority'] = float(slit.getAttribute('priority'))
            t['mag'] = float(slit.getAttribute('mag'))
            t['id'] = str(slit.getAttribute('id'))
            Slits[slit.getAttribute('id')] = t
         
        self.loadxmlinfo(Param)
        self.slitlets.readxml(Slits, Refstars)

        # need to add an update all the param field when loading an xml

    def addxmlparameter(self,name,value):
        parameter = self.doc.createElement("parameter")
        parameter.setAttribute('name','%s'%name)
        parameter.setAttribute('value','%s'%value)
        return parameter

    def writexml(self):
        '''
        write out the slitmask and slits info to a xml file.
        '''

        print 'writing xml...'
         #create the xml documents and the main Element called slitmask
        self.doc = self.impl.createDocument(None, "slitmask", None)
        slitmask= self.doc.documentElement
        header = self.doc.createElement("header")
        slitmask.appendChild(header)

        header.appendChild(self.addxmlparameter("VERSION","1.1"))
        header.appendChild(self.addxmlparameter("PROPOSALCODE","%s"%self.proposal_code))
        header.appendChild(self.addxmlparameter("MASKNUM","%s"%self.mask_name))
        header.appendChild(self.addxmlparameter("TARGET","%s"%self.target_name))
        header.appendChild(self.addxmlparameter("PI","%s"%self.proposer))
        header.appendChild(self.addxmlparameter("CREATOR","%s"%self.creator))
        header.appendChild(self.addxmlparameter("ROTANGLE","%s"%self.position_angle))
        header.appendChild(self.addxmlparameter("CENTERRA","%f"%self.center_ra))
        header.appendChild(self.addxmlparameter("CENTERDEC","%f"%self.center_dec))
        header.appendChild(self.addxmlparameter("NSMODE","0"))
        header.appendChild(self.addxmlparameter("VALIDATED","%s"%str(self.validated)))
        header.appendChild(self.addxmlparameter("SPECLENGTH","12400"))
        header.appendChild(self.addxmlparameter("SPECOFFSET","0"))
        header.appendChild(self.addxmlparameter("SPECPOLSPLIT","0"))
        header.appendChild(self.addxmlparameter("SPECHEIGHT","0"))


        for i in range(0,len(self.slitlets.data)):
          if self.slitlets.data['inmask_flag'][i]:
            slitcard = self.slitlets.asxml(i)
            slitmask.appendChild(slitcard)

        xml = self.doc.toprettyxml(indent="  ")
        return xml

    def outFoV_row(self,i):
        '''
        checks if a single row in the slitlets.data array is outside the FoV
        input is a slitlets.data row
        '''

        # first check that the mask info has been defined, otherwise all
        # slits fall outside the FoV
        if self.center_ra == None or self.center_dec == None\
            or self.position_angle == None or self.equinox == None:
                self.slitlets.data[i]['fov_flag'] = 0
                return
        else:
            pass

        pixscale = 0.2507 / 2. # unbinned pixels

        dcr = 4. / 60. # radius of field (deg)
        # global CCD parameters:
        ccd_dx = 2034.
        ccd_xgap = 70.
        ccd_dy = 4102.

        # define centre in pixel coords
        ccd_cx = (2. * (ccd_dx + ccd_xgap) + ccd_dx) / 2.
        ccd_cy = ccd_dy / 2.

        wcs = pywcs.WCS(naxis=2)
        wcs.wcs.crpix = [ccd_cx,ccd_cy]
        wcs.wcs.cdelt = np.array([-pixscale, pixscale]) / 3600. # set in degrees
        wcs.wcs.crval = [self.center_ra, self.center_dec]
        wcs.wcs.ctype = ["RA---TAN", "DEC--TAN"]
        wcs.wcs.crota = [self.position_angle, self.position_angle] # rotate SKY this amount?
        wcs.wcs.equinox = self.equinox

        # convert onsky coords to pix
        xp,yp = wcs.wcs_sky2pix(self.slitlets.data[i]['targ_ra'],\
                                self.slitlets.data[i]['targ_dec'], 1)

        # testing for all four slit corners
        # upper left corner
        ulx = xp - (self.slitlets.data[i]['slit_width'] /2. ) / pixscale
        uly = yp + self.slitlets.data[i]['len1'] / pixscale
        # upper right corner
        urx = xp + (self.slitlets.data[i]['slit_width'] / 2.)/ pixscale
        ury = yp + self.slitlets.data[i]['len1'] / pixscale
        # lower left corner
        llx = xp - (self.slitlets.data[i]['slit_width'] / 2.) / pixscale
        lly = yp - self.slitlets.data[i]['len2'] / pixscale
        # lower right corner
        lrx = xp + (self.slitlets.data[i]['slit_width'] /2. ) / pixscale
        lry = yp - self.slitlets.data[i]['len2'] / pixscale

        # determine the distances to each corner
        uldist = (uly - ccd_cy)**2 + (ulx - ccd_cx)**2
        urdist = (ury - ccd_cy)**2 + (urx - ccd_cx)**2
        lldist = (lly - ccd_cy)**2 + (llx - ccd_cx)**2
        lrdist = (lry - ccd_cy)**2 + (lrx - ccd_cx)**2

        # test if each corner lies outside the FoV, the boolean array returns
        # true if a corner lies outside the FoV
        maxdist = (dcr * 3600.0 / pixscale)**2
        ultest = uldist <= maxdist
        urtest = urdist <= maxdist
        lltest = lldist <= maxdist
        lrtest = lrdist <= maxdist

        # the slitlet lies in the FoV only if all tests were passed
        # if only one test is failed its False
    
        pass_test = ultest * urtest * lltest * lrtest

        # convert the list to a np array
        pass_test = np.array(pass_test)


        # set the FoV flag for slits inside the FoV
        self.slitlets.data[i]['fov_flag'] = 1 * pass_test[0]

        return

    def outFoV(self):
        '''
        this function goes throught slitlets.data and populates the FoV flag
        using the outFoV_row function for each entry in the array
        '''
        
        for i in range(0,len(self.slitlets.data)):
            self.outFoV_row(i)
            
        return

    def find_collisions(self):
        '''
        this function checks for slit collisions
        '''
        idebug = 1
        if idebug: print "Checking for collisions"

        # xleft,xright are spectral lengths in pixels - set to large dummy values for now

        # **** again, only does special case of PA=0/180, no slit tilt...
        #if not ( self.position_angle == 0 or self.position_angle == 180):
        #   msg='Collision checking only works at position angles of 0 or 180'
        #   print msg
        #   self.slitlets.data['collision_flag'] = 0
        #   return

        # first check that the mask info has been defined, otherwise
        # no collision checking can be done
        if self.center_ra == None or self.center_dec == None\
            or self.position_angle == None or self.equinox == None:
                self.slitlets.data['collision_flag'] = 0
                return
        else:
            pass

        print self.center_ra, self.center_dec, self.position_angle

        # setup default values:
        #slit_ra,slit_dec,slit_length,slit_width,cra,cdec,rotang,equinox,xpad,ypad,xleft,xright

        pixscale = 0.129 # unbinned pixels
#        xpad = 1
#        xright = 1
#        xleft = 1
        ypad = 1. / pixscale



        # global CCD parameters:
        ccd_dx = 2034.
        ccd_xgap = 70.
        ccd_dy = 4102.

        # define centre in pixel coords
        ccd_cx = (2. * (ccd_dx + ccd_xgap) + ccd_dx) / 2.
        ccd_cy = ccd_dy / 2.

        wcs = pywcs.WCS(naxis=2)
        wcs.wcs.crpix = [ccd_cx,ccd_cy]
        wcs.wcs.cdelt = np.array([-pixscale, pixscale]) / 3600. # set in degrees
        wcs.wcs.crval = [self.center_ra, self.center_dec]
        wcs.wcs.ctype = ["RA---TAN", "DEC--TAN"]
        wcs.wcs.crota = [self.position_angle, self.position_angle] # rotate SKY this amount?
        wcs.wcs.equinox = self.equinox

        #TODO: only slits that lie in the FoV should be checked for collisions
        is_in_mask = np.where((self.slitlets.data['inmask_flag'] == 1) * (self.slitlets.data['fov_flag'] == 1))[0]
        print 'is in mask', is_in_mask
        if not is_in_mask.any():  
           msg='No objects in mask'
           print msg
           self.slitlets.data['collision_flag'] = 0
           return

        # convert onsky coords to pix
        xp, yp = wcs.wcs_sky2pix(self.slitlets.data['targ_ra'][is_in_mask],
                                 self.slitlets.data['targ_dec'][is_in_mask], 1)
       
        slit_length = (self.slitlets.data['len1'][is_in_mask] + self.slitlets.data['len2'][is_in_mask]) / pixscale
        nslits = len(is_in_mask)
        coll_flag = [False] * nslits
        coll_ids = [None] * nslits ## can assign a list of collisions to any item in this list

        # **** i think for general case i just need to replace slit width below with projected height which would be:
        #      total_height = slit_length*cos(theta) + 2.* 0.5 * slit_width*sin(theta)
        #         where theta is some combination of rotang and tilt
        #
        # need to update optimiser for more general case, too.
#        tx0 = xp - xleft - (xpad / 2.)
#        tx1 = xp + xright + (xpad / 2.) # [ careful switching between lower left and width and lower left and upper right notation ]
        ymin = yp - (slit_length / 2.) - (ypad / 2.)
        ymax = yp + (slit_length / 2.) + (ypad / 2.)

        # dumb but reliable way of checking:
        for i in range(nslits):
            self.slitlets.data['collision_flag'][is_in_mask[i]] = 0
            self.slitlets.data['collision_id'][is_in_mask[i]]= []

            tcoll_ids=[]
            for j in range(nslits):
                if i != j:
                   if (ymax[i] > ymin[j] and ymax[i] < ymax[j]) or (ymin[i] < ymax[j] and ymin[i] > ymin[j]):
                        self.slitlets.data['collision_flag'][is_in_mask[i]] = 1
                        tcoll_ids.append(self.slitlets.data[is_in_mask[j]]['name'])
                        print self.slitlets.data['name'][is_in_mask[i]], self.slitlets.data['collision_flag'][is_in_mask[i]]
                        
            if self.slitlets.data['collision_flag'][is_in_mask[i]]:
               self.slitlets.data['collision_id'][is_in_mask[i]] = " ".join(['%s' % x for x in tcoll_ids])
               print self.slitlets.data['collision_id'][is_in_mask[i]]

        print 'Finished Checking for collisions'
        self.slitlets.update_flags()
        
    def update_fov_slitlets(self):
        changed = False
        if changed:
            # send signal
            pass

    def add_slitlet(self, slitlet, in_mask=False):
        self.__all_slitlets[slitlet.id] = slitlet
        # connect to slit
        # send signal
        if in_mask:
            self.__mask_slitlets.add(slitlet.id)
            # send signal

    def remove_slitlet(self, slitlet):
        del(self.__all_slitlets[slitlet.id])
        # disconnect from slitlet
        # send signal
        if slitlet.id in self.__mask_slitlets:
            self.__mask_slitlets.remove(slitlet.id)
            # send signal
        if slitlet.id in self.__fov_slitlets:
            self.__fov_slitlets.remove(slitlet.id)
            # send signal

    def add_to_mask(self, slitlet):
        if not slitlet.id in self.__all_slitlets.keys():
            raise SlitError()
        if slitlet.id in self.__mask_slitlets:
            return
        self.__mask_slitlets.add(slitlet.id)
        # send signal
        # update FOV list?
        # update collisions

    def remove_from_mask(self, slitlet):
        if not slitlet.id in self.__mask_slitlets:
            return
        self.__mask_slitlets.remove(slitlet.id)
        # send signal
        # update FOV list?
        # update collisions

    def slitlet_changed(self, slitlet):
        """callback method for handling slit changes
        """
        # update FOV list?
        # update collisions
        pass

    @staticmethod
    def is_in_fov(slitlet):
        pass

    @staticmethod
    def read_from_file():
        pass

#    def FOVTest(cra,cdec,equinox,rotang,slitra,slitdec,slit_length,tilt):
    def outFoV_all(self):

        # first check that the mask info has been defined, otherwise all
        # slits fall outside the FoV
        if self.center_ra == None or self.center_dec == None\
            or self.position_angle == None or self.equinox == None:
                self.slitlets.data['fov_flag'] = 0
                return
        else:
            pass

        pixscale = 0.2507 / 2. # unbinned pixels

        dcr = 4. / 60. # radius of field (deg)
        # global CCD parameters:
        ccd_dx = 2034.
        ccd_xgap = 70.
        ccd_dy = 4102.

        # define centre in pixel coords
        ccd_cx = (2.*(ccd_dx + ccd_xgap) + ccd_dx) / 2.
        ccd_cy = ccd_dy / 2.

        # setup the field WCS coords.
        wcs = pywcs.WCS(naxis=2)
        wcs.wcs.crpix = [ccd_cx,ccd_cy]
        wcs.wcs.cdelt = np.array([-pixscale, pixscale]) / 3600. # set in degrees
        wcs.wcs.crval = [self.center_ra, self.center_dec]
        wcs.wcs.ctype = ["RA---TAN", "DEC--TAN"]
        wcs.wcs.crota = [self.position_angle, self.position_angle] # rotate SKY this amount?
        wcs.wcs.equinox = self.equinox

        # convert onsky coords to pix
        xp, yp = wcs.wcs_sky2pix(self.slitlets.data['targ_ra'],
                                self.slitlets.data['targ_dec'], 1)

        # testing for all four slit corners
        # upper left corner
        ulx = xp - (self.slitlets.data['slit_width'] /2. ) / pixscale
        uly = yp + self.slitlets.data['len1'] / pixscale
        # upper right corner
        urx = xp + (self.slitlets.data['slit_width'] / 2.) / pixscale
        ury = yp + self.slitlets.data['len1'] / pixscale
        # lower left corner
        llx = xp - (self.slitlets.data['slit_width'] / 2.) / pixscale
        lly = yp - self.slitlets.data['len2'] / pixscale
        # lower right corner
        lrx = xp + (self.slitlets.data['slit_width'] /2. ) / pixscale
        lry = yp - self.slitlets.data['len2'] / pixscale

        # determine the distances to each corner
        uldist = (uly - ccd_cy)**2 + (ulx - ccd_cx)**2
        urdist = (ury - ccd_cy)**2 + (urx - ccd_cx)**2
        lldist = (lly - ccd_cy)**2 + (llx - ccd_cx)**2
        lrdist = (lry - ccd_cy)**2 + (lrx - ccd_cx)**2

        # test if each corner lies outside the FoV, the boolean array returns
        # true if a corner lies outside the FoV
        maxdist = (dcr * 3600.0 / pixscale)**2
        ultest = uldist <= maxdist
        urtest = urdist <= maxdist
        lltest = lldist <= maxdist
        lrtest = lrdist <= maxdist

        # the slitlet lies in the FoV only if all tests were passed
        # if only one test is failed its False
        pass_test = ultest * urtest * lltest * lrtest

        # convert the list to a np array
        pass_test = np.array(pass_test)

        # set the FoV flag for slits inside the FoV

        self.slitlets.data['fov_flag'] = 1 * pass_test

        return
Beispiel #3
0
class OptimizeTab:
    def __init__(self, ui, default_yspacing=1., default_iter=10):
        print 'loading OPT'
        self.ui = ui
        self.slitlets = Slitlets()
        self.opt_yspacing = default_yspacing
        self.opt_niter = default_iter

    def setoptimizer_yspacing(self):
        self.opt_yspacing = self.checkyspacing_input(
            self.ui.lineEditOpt_Yspacing.text())

    def setoptimizer_iter(self):
        self.opt_niter = self.checkniter_input(
            self.ui.lineEditOpt_Niter.text())

    def includerefstars(self):
        if self.ui.checkBoxOpt_IncRefstars.isChecked():
            nrefstars = len(np.where(self.slitlets.data['priority'] == -1)[0])
            self.ui.lineEditOpt_AllRefstars.setText(str(nrefstars))
        else:
            self.ui.lineEditOpt_AllRefstars.setText('')

    def setnumrefstars(self):
        print self.ui.lineEditOpt_NumRefstars.text()

    def optimize(self):
        """Run the optimizer program and optimize the slits"""
        msg = "Optimize the Slitlets"
        print msg
        cra = self.slitmask.center_ra
        cdec = self.slitmask.center_dec
        rotang = self.slitmask.position_angle
        equinox = 2000
        is_in_fov = np.where(self.slitlets.data['fov_flag'] == 1)[0]

        # jpk: this will need to be added in the next version
        #        is_in_fov = np.where((self.slitlets.data['inmask_flag'] == 1) * (self.slitlets.data['fov_flag'] == 1))[0]

        ra = self.slitlets.data['targ_ra']
        dec = self.slitlets.data['targ_dec']
        pri = self.slitlets.data['priority']
        slen = self.slitlets.data['len1'] + self.slitlets.data['len2']
        swid = self.slitlets.data['width']
        stilt = self.slitlets.data['tilt']

        Nstars_req = 0.  # **** Paul: I'm not quite sure where to get this from ****
        Niter = 10  # **** as above ****
        # set all inmask flags to zero before running optimiser
        #self.slitlets.emptymask()

        # -- only run this on objects within FOV:
        ok = is_in_fov
        if not ok.any():
            print "No objects in the field of view--update mask center and run again"
            return

        print ra[ok]
        tra = ra[ok]
        tdec = dec[ok]
        tpri = pri[ok]
        tslen = slen[ok]
        tswid = swid[ok]
        tstilt = stilt[ok]
        print 'running optimizer'

        tin_mask = opt.pyslit_optimize(cra, cdec, rotang, equinox, tra, tdec, \
                                    tpri,tslen,tswid,tstilt,\
                                    Niter,self.opt_yspacing, Nstars_req)
        # apply index numbers to full list:
        in_mask = ok[tin_mask]

        # reset all the in_mask values, otherwise the objects which should not
        # be in the optimized mask will still have a in_mask flag
        self.slitlets.data['inmask_flag'] = 0
        self.slitlets.data['collision_flag'] = 0

        # now add the in_mask flag to the sources which was found by the
        # optimizer
        for sid in in_mask:
            self.slitlets.addtomask(sid)
        self.updatetabs()

    def updatetabs(self):
        self.slitmask.outFoV_all()
        self.slitmask.find_collisions()
        self.slitlets.update_flags()
#        pass

    def checkyspacing_input(self, x):
        try:
            val = float(x)
            if val > 0:
                return val
            else:
                self.opt_yspacing = 1
                self.ui.lineEditOpt_Yspacing.setText(str(self.opt_yspacing))
        except ValueError, e:
            self.opt_yspacing = 1
            self.ui.lineEditOpt_Yspacing.setText(str(self.opt_yspacing))
Beispiel #4
0
class SlitMask(QObject):
    def __init__(self,
                 center_ra=None,
                 center_dec=None,
                 position_angle=0,
                 target_name='',
                 mask_name='',
                 equinox=2000,
                 proposal_code='',
                 proposer='',
                 creator='',
                 validated=False):
        super(QObject, self).__init__()
        self.__center_ra = None
        self.__center_dec = None
        self.__position_angle = None
        self.__equinox = None
        self.add_center_ra(center_ra)
        self.add_center_dec(center_dec)
        self.add_position_angle(position_angle)
        self.add_equinox(equinox)

        self.target_name = target_name
        self.mask_name = mask_name
        self.proposal_code = proposal_code
        self.proposer = proposer
        self.creator = creator
        self.validated = validated

        #create the slitlets
        self.slitlets = Slitlets()

        #needed for writing xml
        self.impl = getDOMImplementation()

#        self.connect(self, SIGNAL('xmlloaded'), self.printcreator)

    @property
    def center_ra(self):
        return self.__center_ra

    @property
    def center_dec(self):
        return self.__center_dec

    @property
    def position_angle(self):
        return self.__position_angle

    @property
    def equinox(self):
        return self.__equinox

    def add_center_ra(self, new_center_ra):
        if new_center_ra is None:
            self.__center_ra = None
            return
        if new_center_ra < 0 or new_center_ra >= 360:
            self.__center_ra = None
            #            raise SlitMaskError()
            return
        changed = new_center_ra != self.__center_ra
        self.__center_ra = new_center_ra
        if changed:
            pass
            # send signal

    def add_center_dec(self, new_center_dec):

        if new_center_dec is None:
            self.__center_dec = None
            return
        if new_center_dec < -90 or new_center_dec > 90:
            self.__center_dec = None
            #            raise SlitMaskError()
            return
        changed = new_center_dec != self.__center_dec
        self.__center_dec = new_center_dec
        if changed:
            pass
            # send signal

    def add_position_angle(self, new_position_angle):
        """Update the value of the position angle"""
        #if None, keep as none
        if new_position_angle is None:
            self.__position_angle = None
            return
        #if a str is given, try to update to a float

        if new_position_angle < 0 or new_position_angle > 360:
            self.__position_angle = None
            return
        changed = new_position_angle != self.__position_angle
        self.__position_angle = new_position_angle
        if changed:
            pass
            # send signal

    def add_equinox(self, new_equinox):
        """Update the equinox value"""
        #if None, keep as none
        if new_equinox is None:
            self.__equinox = None
            return
        if new_equinox < 0:
            self.__equinox = None
            return
#                raise SlitMaskError()
        changed = new_equinox != self.__equinox
        self.__equinox = new_equinox
        if changed:
            pass
            # send signal

    def set_MaskPosition(self):
        """Sets the central mask position from the current slit positions.  The setting of the mask position works on the following
          priority: 1) If an object is givne with a priority of 2, that object sets the masks position.  2) If objects are
          pre-selected to be in the mask, they set the center position of the mask.  3) Set the center position to be at the 
          center of the catalog
       """
        #get the arrays that you might need
        priority = self.slitlets.data['priority']
        inmask = self.slitlets.data['inmask_flag']
        ra = self.slitlets.data['targ_ra']
        dec = self.slitlets.data['targ_dec']

        if priority.any() >= 2:
            cen_ra = ra[priority == 2].mean()
            cen_dec = dec[priority == 2].mean()
        elif inmask.any():
            cen_ra = ra[inmask == 1].mean()
            cen_dec = dec[inmask == 1].mean()
        else:
            cen_ra = ra.mean()
            cen_dec = dec.mean()

        self.add_center_ra(cen_ra)
        self.add_center_dec(cen_dec)
        self.add_position_angle(0)

    #
    # ... analogous methods for other properties ...
    #

    def loadxmlinfo(self, par):

        self.proposal_code = par['proposalcode']
        self.proposer = par['pi']
        self.creator = par['creator']
        self.mask_name = par['masknum']
        self.validated = par['validated']
        self.add_center_ra(float(par['centerra']))
        self.add_center_dec(float(par['centerdec']))
        self.add_position_angle(float(par['rotangle']))
        try:
            self.target_name = par['target']
        except:
            pass

#        c = str(self.creator)
#        self.emit(SIGNAL('xmlloaded'), self.creator)

#for testing the emit and connect
#    def printcreator(self, c):
#        print 'the creator is: ', c

    def readmaskxml(self, dom):
        # read all the parameters into dictionaries
        parameters = dom.getElementsByTagName('parameter')

        Param = {}
        for param in parameters:
            Param[str(param.getAttribute('name')).lower()] \
            = str(param.getAttribute('value')).lower()

        # read all the reference stars into dictionaries
        Refstars = {}
        refstars = dom.getElementsByTagName('refstar')
        for refstar in refstars:
            t = {}
            t['xce'] = float(refstar.getAttribute('xce'))
            t['yce'] = float(refstar.getAttribute('yce'))
            t['mag'] = float(refstar.getAttribute('mag'))
            t['id'] = str(refstar.getAttribute('id'))
            Refstars[refstar.getAttribute('id')] = t

        # read all the slits into dictionaries
        Slits = {}
        slits = dom.getElementsByTagName('slit')
        for slit in slits:
            t = {}
            t['xce'] = float(slit.getAttribute('xce'))
            t['yce'] = float(slit.getAttribute('yce'))
            t['width'] = float(slit.getAttribute('width'))
            t['length'] = float(slit.getAttribute('length'))
            t['len1'] = float(slit.getAttribute('length')) / 2.
            t['len2'] = float(slit.getAttribute('length')) / 2.
            t['priority'] = float(slit.getAttribute('priority'))
            t['mag'] = float(slit.getAttribute('mag'))
            t['id'] = str(slit.getAttribute('id'))
            Slits[slit.getAttribute('id')] = t

        self.loadxmlinfo(Param)
        self.slitlets.readxml(Slits, Refstars)

        # need to add an update all the param field when loading an xml

    def addxmlparameter(self, name, value):
        parameter = self.doc.createElement("parameter")
        parameter.setAttribute('name', '%s' % name)
        parameter.setAttribute('value', '%s' % value)
        return parameter

    def writexml(self):
        '''
        write out the slitmask and slits info to a xml file.
        '''

        print 'writing xml...'
        #create the xml documents and the main Element called slitmask
        self.doc = self.impl.createDocument(None, "slitmask", None)
        slitmask = self.doc.documentElement
        header = self.doc.createElement("header")
        slitmask.appendChild(header)

        header.appendChild(self.addxmlparameter("VERSION", "1.1"))
        header.appendChild(
            self.addxmlparameter("PROPOSALCODE", "%s" % self.proposal_code))
        header.appendChild(
            self.addxmlparameter("MASKNUM", "%s" % self.mask_name))
        header.appendChild(
            self.addxmlparameter("TARGET", "%s" % self.target_name))
        header.appendChild(self.addxmlparameter("PI", "%s" % self.proposer))
        header.appendChild(self.addxmlparameter("CREATOR",
                                                "%s" % self.creator))
        header.appendChild(
            self.addxmlparameter("ROTANGLE", "%s" % self.position_angle))
        header.appendChild(
            self.addxmlparameter("CENTERRA", "%f" % self.center_ra))
        header.appendChild(
            self.addxmlparameter("CENTERDEC", "%f" % self.center_dec))
        header.appendChild(self.addxmlparameter("NSMODE", "0"))
        header.appendChild(
            self.addxmlparameter("VALIDATED", "%s" % str(self.validated)))
        header.appendChild(self.addxmlparameter("SPECLENGTH", "12400"))
        header.appendChild(self.addxmlparameter("SPECOFFSET", "0"))
        header.appendChild(self.addxmlparameter("SPECPOLSPLIT", "0"))
        header.appendChild(self.addxmlparameter("SPECHEIGHT", "0"))

        for i in range(0, len(self.slitlets.data)):
            if self.slitlets.data['inmask_flag'][i]:
                slitcard = self.slitlets.asxml(i)
                slitmask.appendChild(slitcard)

        xml = self.doc.toprettyxml(indent="  ")
        return xml

    def outFoV_row(self, i):
        '''
        checks if a single row in the slitlets.data array is outside the FoV
        input is a slitlets.data row
        '''

        # first check that the mask info has been defined, otherwise all
        # slits fall outside the FoV
        if self.center_ra == None or self.center_dec == None\
            or self.position_angle == None or self.equinox == None:
            self.slitlets.data[i]['fov_flag'] = 0
            return
        else:
            pass

        pixscale = 0.2507 / 2.  # unbinned pixels

        dcr = 4. / 60.  # radius of field (deg)
        # global CCD parameters:
        ccd_dx = 2034.
        ccd_xgap = 70.
        ccd_dy = 4102.

        # define centre in pixel coords
        ccd_cx = (2. * (ccd_dx + ccd_xgap) + ccd_dx) / 2.
        ccd_cy = ccd_dy / 2.

        wcs = pywcs.WCS(naxis=2)
        wcs.wcs.crpix = [ccd_cx, ccd_cy]
        wcs.wcs.cdelt = np.array([-pixscale, pixscale
                                  ]) / 3600.  # set in degrees
        wcs.wcs.crval = [self.center_ra, self.center_dec]
        wcs.wcs.ctype = ["RA---TAN", "DEC--TAN"]
        wcs.wcs.crota = [self.position_angle,
                         self.position_angle]  # rotate SKY this amount?
        wcs.wcs.equinox = self.equinox

        # convert onsky coords to pix
        xp,yp = wcs.wcs_sky2pix(self.slitlets.data[i]['targ_ra'],\
                                self.slitlets.data[i]['targ_dec'], 1)

        # testing for all four slit corners
        # upper left corner
        ulx = xp - (self.slitlets.data[i]['slit_width'] / 2.) / pixscale
        uly = yp + self.slitlets.data[i]['len1'] / pixscale
        # upper right corner
        urx = xp + (self.slitlets.data[i]['slit_width'] / 2.) / pixscale
        ury = yp + self.slitlets.data[i]['len1'] / pixscale
        # lower left corner
        llx = xp - (self.slitlets.data[i]['slit_width'] / 2.) / pixscale
        lly = yp - self.slitlets.data[i]['len2'] / pixscale
        # lower right corner
        lrx = xp + (self.slitlets.data[i]['slit_width'] / 2.) / pixscale
        lry = yp - self.slitlets.data[i]['len2'] / pixscale

        # determine the distances to each corner
        uldist = (uly - ccd_cy)**2 + (ulx - ccd_cx)**2
        urdist = (ury - ccd_cy)**2 + (urx - ccd_cx)**2
        lldist = (lly - ccd_cy)**2 + (llx - ccd_cx)**2
        lrdist = (lry - ccd_cy)**2 + (lrx - ccd_cx)**2

        # test if each corner lies outside the FoV, the boolean array returns
        # true if a corner lies outside the FoV
        maxdist = (dcr * 3600.0 / pixscale)**2
        ultest = uldist <= maxdist
        urtest = urdist <= maxdist
        lltest = lldist <= maxdist
        lrtest = lrdist <= maxdist

        # the slitlet lies in the FoV only if all tests were passed
        # if only one test is failed its False

        pass_test = ultest * urtest * lltest * lrtest

        # convert the list to a np array
        pass_test = np.array(pass_test)

        # set the FoV flag for slits inside the FoV
        self.slitlets.data[i]['fov_flag'] = 1 * pass_test[0]

        return

    def outFoV(self):
        '''
        this function goes throught slitlets.data and populates the FoV flag
        using the outFoV_row function for each entry in the array
        '''

        for i in range(0, len(self.slitlets.data)):
            self.outFoV_row(i)

        return

    def find_collisions(self):
        '''
        this function checks for slit collisions
        '''
        idebug = 1
        if idebug: print "Checking for collisions"

        # xleft,xright are spectral lengths in pixels - set to large dummy values for now

        # **** again, only does special case of PA=0/180, no slit tilt...
        #if not ( self.position_angle == 0 or self.position_angle == 180):
        #   msg='Collision checking only works at position angles of 0 or 180'
        #   print msg
        #   self.slitlets.data['collision_flag'] = 0
        #   return

        # first check that the mask info has been defined, otherwise
        # no collision checking can be done
        if self.center_ra == None or self.center_dec == None\
            or self.position_angle == None or self.equinox == None:
            self.slitlets.data['collision_flag'] = 0
            return
        else:
            pass

        print self.center_ra, self.center_dec, self.position_angle

        # setup default values:
        #slit_ra,slit_dec,slit_length,slit_width,cra,cdec,rotang,equinox,xpad,ypad,xleft,xright

        pixscale = 0.129  # unbinned pixels
        #        xpad = 1
        #        xright = 1
        #        xleft = 1
        ypad = 1. / pixscale

        # global CCD parameters:
        ccd_dx = 2034.
        ccd_xgap = 70.
        ccd_dy = 4102.

        # define centre in pixel coords
        ccd_cx = (2. * (ccd_dx + ccd_xgap) + ccd_dx) / 2.
        ccd_cy = ccd_dy / 2.

        wcs = pywcs.WCS(naxis=2)
        wcs.wcs.crpix = [ccd_cx, ccd_cy]
        wcs.wcs.cdelt = np.array([-pixscale, pixscale
                                  ]) / 3600.  # set in degrees
        wcs.wcs.crval = [self.center_ra, self.center_dec]
        wcs.wcs.ctype = ["RA---TAN", "DEC--TAN"]
        wcs.wcs.crota = [self.position_angle,
                         self.position_angle]  # rotate SKY this amount?
        wcs.wcs.equinox = self.equinox

        #TODO: only slits that lie in the FoV should be checked for collisions
        is_in_mask = np.where((self.slitlets.data['inmask_flag'] == 1) *
                              (self.slitlets.data['fov_flag'] == 1))[0]
        print 'is in mask', is_in_mask
        if not is_in_mask.any():
            msg = 'No objects in mask'
            print msg
            self.slitlets.data['collision_flag'] = 0
            return

        # convert onsky coords to pix
        xp, yp = wcs.wcs_sky2pix(self.slitlets.data['targ_ra'][is_in_mask],
                                 self.slitlets.data['targ_dec'][is_in_mask], 1)

        slit_length = (self.slitlets.data['len1'][is_in_mask] +
                       self.slitlets.data['len2'][is_in_mask]) / pixscale
        nslits = len(is_in_mask)
        coll_flag = [False] * nslits
        coll_ids = [
            None
        ] * nslits  ## can assign a list of collisions to any item in this list

        # **** i think for general case i just need to replace slit width below with projected height which would be:
        #      total_height = slit_length*cos(theta) + 2.* 0.5 * slit_width*sin(theta)
        #         where theta is some combination of rotang and tilt
        #
        # need to update optimiser for more general case, too.
        #        tx0 = xp - xleft - (xpad / 2.)
        #        tx1 = xp + xright + (xpad / 2.) # [ careful switching between lower left and width and lower left and upper right notation ]
        ymin = yp - (slit_length / 2.) - (ypad / 2.)
        ymax = yp + (slit_length / 2.) + (ypad / 2.)

        # dumb but reliable way of checking:
        for i in range(nslits):
            self.slitlets.data['collision_flag'][is_in_mask[i]] = 0
            self.slitlets.data['collision_id'][is_in_mask[i]] = []

            tcoll_ids = []
            for j in range(nslits):
                if i != j:
                    if (ymax[i] > ymin[j]
                            and ymax[i] < ymax[j]) or (ymin[i] < ymax[j]
                                                       and ymin[i] > ymin[j]):
                        self.slitlets.data['collision_flag'][is_in_mask[i]] = 1
                        tcoll_ids.append(
                            self.slitlets.data[is_in_mask[j]]['name'])
                        print self.slitlets.data['name'][is_in_mask[
                            i]], self.slitlets.data['collision_flag'][
                                is_in_mask[i]]

            if self.slitlets.data['collision_flag'][is_in_mask[i]]:
                self.slitlets.data['collision_id'][is_in_mask[i]] = " ".join(
                    ['%s' % x for x in tcoll_ids])
                print self.slitlets.data['collision_id'][is_in_mask[i]]

        print 'Finished Checking for collisions'
        self.slitlets.update_flags()

    def update_fov_slitlets(self):
        changed = False
        if changed:
            # send signal
            pass

    def add_slitlet(self, slitlet, in_mask=False):
        self.__all_slitlets[slitlet.id] = slitlet
        # connect to slit
        # send signal
        if in_mask:
            self.__mask_slitlets.add(slitlet.id)
            # send signal

    def remove_slitlet(self, slitlet):
        del (self.__all_slitlets[slitlet.id])
        # disconnect from slitlet
        # send signal
        if slitlet.id in self.__mask_slitlets:
            self.__mask_slitlets.remove(slitlet.id)
            # send signal
        if slitlet.id in self.__fov_slitlets:
            self.__fov_slitlets.remove(slitlet.id)
            # send signal

    def add_to_mask(self, slitlet):
        if not slitlet.id in self.__all_slitlets.keys():
            raise SlitError()
        if slitlet.id in self.__mask_slitlets:
            return
        self.__mask_slitlets.add(slitlet.id)
        # send signal
        # update FOV list?
        # update collisions

    def remove_from_mask(self, slitlet):
        if not slitlet.id in self.__mask_slitlets:
            return
        self.__mask_slitlets.remove(slitlet.id)
        # send signal
        # update FOV list?
        # update collisions

    def slitlet_changed(self, slitlet):
        """callback method for handling slit changes
        """
        # update FOV list?
        # update collisions
        pass

    @staticmethod
    def is_in_fov(slitlet):
        pass

    @staticmethod
    def read_from_file():
        pass


#    def FOVTest(cra,cdec,equinox,rotang,slitra,slitdec,slit_length,tilt):

    def outFoV_all(self):

        # first check that the mask info has been defined, otherwise all
        # slits fall outside the FoV
        if self.center_ra == None or self.center_dec == None\
            or self.position_angle == None or self.equinox == None:
            self.slitlets.data['fov_flag'] = 0
            return
        else:
            pass

        pixscale = 0.2507 / 2.  # unbinned pixels

        dcr = 4. / 60.  # radius of field (deg)
        # global CCD parameters:
        ccd_dx = 2034.
        ccd_xgap = 70.
        ccd_dy = 4102.

        # define centre in pixel coords
        ccd_cx = (2. * (ccd_dx + ccd_xgap) + ccd_dx) / 2.
        ccd_cy = ccd_dy / 2.

        # setup the field WCS coords.
        wcs = pywcs.WCS(naxis=2)
        wcs.wcs.crpix = [ccd_cx, ccd_cy]
        wcs.wcs.cdelt = np.array([-pixscale, pixscale
                                  ]) / 3600.  # set in degrees
        wcs.wcs.crval = [self.center_ra, self.center_dec]
        wcs.wcs.ctype = ["RA---TAN", "DEC--TAN"]
        wcs.wcs.crota = [self.position_angle,
                         self.position_angle]  # rotate SKY this amount?
        wcs.wcs.equinox = self.equinox

        # convert onsky coords to pix
        xp, yp = wcs.wcs_sky2pix(self.slitlets.data['targ_ra'],
                                 self.slitlets.data['targ_dec'], 1)

        # testing for all four slit corners
        # upper left corner
        ulx = xp - (self.slitlets.data['slit_width'] / 2.) / pixscale
        uly = yp + self.slitlets.data['len1'] / pixscale
        # upper right corner
        urx = xp + (self.slitlets.data['slit_width'] / 2.) / pixscale
        ury = yp + self.slitlets.data['len1'] / pixscale
        # lower left corner
        llx = xp - (self.slitlets.data['slit_width'] / 2.) / pixscale
        lly = yp - self.slitlets.data['len2'] / pixscale
        # lower right corner
        lrx = xp + (self.slitlets.data['slit_width'] / 2.) / pixscale
        lry = yp - self.slitlets.data['len2'] / pixscale

        # determine the distances to each corner
        uldist = (uly - ccd_cy)**2 + (ulx - ccd_cx)**2
        urdist = (ury - ccd_cy)**2 + (urx - ccd_cx)**2
        lldist = (lly - ccd_cy)**2 + (llx - ccd_cx)**2
        lrdist = (lry - ccd_cy)**2 + (lrx - ccd_cx)**2

        # test if each corner lies outside the FoV, the boolean array returns
        # true if a corner lies outside the FoV
        maxdist = (dcr * 3600.0 / pixscale)**2
        ultest = uldist <= maxdist
        urtest = urdist <= maxdist
        lltest = lldist <= maxdist
        lrtest = lrdist <= maxdist

        # the slitlet lies in the FoV only if all tests were passed
        # if only one test is failed its False
        pass_test = ultest * urtest * lltest * lrtest

        # convert the list to a np array
        pass_test = np.array(pass_test)

        # set the FoV flag for slits inside the FoV

        self.slitlets.data['fov_flag'] = 1 * pass_test

        return
Beispiel #5
0
class SlitTab:
    def __init__(self, ui, infile=None):
        self.ui = ui
        self.slitlets=Slitlets()
        self.infile=infile
        self.cell = None
        self.rows = None

    def unique(self,seq):
        '''
        return a unique number of rows from the table selection
        '''
        seen = set()
        seen_add = seen.add
        return [ x for x in seq if x not in seen and not seen_add(x)]

    def setposition(self):
        '''
        determine the which rows are selected for the deletion on slits
        '''
        self.rows = []
        indexes = self.ui.tableWidgetSlits.selectedIndexes()
        for index in indexes:
            self.rows.append(index.row())
        self.rows = self.unique(self.rows)
        print(self.rows)


    def clearslittable(self):
        '''
        set all the in_mask flags to 0 and update the slit table
        '''
        rows = self.ui.tableWidgetSlits.rowCount()
        print(rows)
        self.slitlets.data['inmask_flag'] = 0
        self.updatetabs()
#        self.ui.tableWidgetSlits.clear()
#        for i in range(0,rows):
#            print i
#            self.ui.tableWidgetSlits.removeRow(i)

    def addslitmanually(self):
        '''
        add an empy row to the slit table that the user must fill in manually
        '''
#        rows = self.ui.tableWidgetSlits.rowCount()
#        print rows
#        if rows > 0:
#            self.ui.tableWidgetSlits.setRowCount(rows+1)
##            self.ui.tableWidgetSlits.insertRow(rows+1)
#            for j in range(len(catcolumn_list)):
#                item = self.parseItem('')
#                self.ui.tableWidgetSlits.setItem(rows+1,j,item)
#        else:
#            self.ui.tableWidgetSlits.setRowCount(0)
#            self.ui.tableWidgetSlits.insertRow(0)
#            for j in range(len(catcolumn_list)):
#                item = self.parseItem('')
#                self.ui.tableWidgetSlits.setItem(rows+1,j,item)

        ######### TESTING: ###########
        self.slitlets.add_slitlet()
        self.slitmask.outFoV()
        self.updatetabs()

    def deleteslitmanually(self):
        '''
        set the selected slits inmask_flag to 0, if none were slected, do nothing
        '''

        if len(self.rows) == 0:
            return
        else:
            print(self.rows)
            for i in self.rows:
                item = self.ui.tableWidgetSlits.item(i,0)
                name = str(item.text())
                ai = np.where(self.slitlets.data['name'] == name)
                self.slitlets.data[ai[0][0]]['inmask_flag'] = 0
        self.slitlets.update_flags()
        self.updatetabs()
        return

    def addslitletsfromcatalogue(self):
        '''
        if a slit has a priority >=0 add it to the slits table.
        * if slits have been added manually before adding from the catalogue
        the row count is set accordingly
        TODO: add in the FoV checker before loading slits and set the appropriate
        flags
        '''
        slits = np.where((self.slitlets.data['priority'] >= 0) * (self.slitlets.data['fov_flag'] == 1))
        for i in slits[0]:
            self.slitlets.data[i]['inmask_flag'] = 1
        self.slitmask.outFoV_all()
        self.slitmask.find_collisions()
        self.slitlets.update_flags()
        self.updatetabs()
        
#        rows = self.ui.tableWidgetSlits.rowCount()
#        if rows > 0:
#            self.ui.tableWidgetSlits.setRowCount(rows+1)
#            row = rows+1
#        else:
#            self.ui.tableWidgetSlits.setRowCount(0)
#            row = 0
#
#        for i in slits[0]:
#            self.ui.tableWidgetSlits.insertRow(row)
#            for j in range(len(catcolumn_list)-1):
#                item=self.parseItem(self.slitlets.data[catcolumn_list[j]][i])
#                self.ui.tableWidgetSlits.setItem(row,j,item)
#            row+=1
       


    def updateslittable(self):
        """Using the slitlet object, update the slit table"""

        # check which entries are in the mask and not reference stars
        inmask = np.where((self.slitlets.data['inmask_flag'] == 1)*(self.slitlets.data['refstar_flag'] == 0))
        
        #enter the information into the table
        self.ui.tableWidgetSlits.setRowCount(0)
        nobj = 0
        for i in inmask[0]:
            self.ui.tableWidgetSlits.insertRow(nobj)
            for j in range(len(catcolumn_list)):
                item=self.parseItem(self.slitlets.data[catcolumn_list[j]][i])
                self.ui.tableWidgetSlits.blockSignals(True)
                self.ui.tableWidgetSlits.setItem(nobj,j,item)
                self.ui.tableWidgetSlits.blockSignals(False)
            nobj += 1
#        for i in range(self.slitlets.nobjects):
#            if self.slitlets.data['inmask_flag'][i]==1:
#
#                if nobj>self.ui.tableWidgetSlits.rowCount():
#                    self.ui.tableWidgetSlits.insertRow(nobj)
#                for j in range(len(catcolumn_list)-1):
#                    f=catcolumn_list[j]
#                    item=self.parseItem(self.slitlets.data[catcolumn_list[j]][i])
#                    self.ui.tableWidgetSlits.setItem(nobj,j,item)
#            nobj+=1

    def slitchanged(self, x ,y):
        """When ever a cell is changed, updated the information about the slit"""
        #identify what slit changed and what attribute of that slit changed
        item = self.ui.tableWidgetSlits.item(x,0)
        name = str(item.text())
        ai = self.slitlets.findslitlet(name)

        #update the attribute
        item=self.ui.tableWidgetSlits.item(x,y)
        self.slitlets.updatevalue(ai, str(item.text()), catcolumn_list[y])

        #update all the tabs
        self.slitmask.outFoV_row(ai)
        self.slitmask.find_collisions()
        self.slitlets.update_flags()
        self.updatetabs()
        
   


    def updatetabs(self):
       """Task designed for overloading"""
       self.updateslittable()
       self.updatecatalogtable()
        
    def parseItem(self, x):
       """Parse an object so it can be entered into the table"""
       if isinstance(x, str):
           return QtGui.QTableWidgetItem(x)
       elif isinstance(x, numpy.float32):
           return QtGui.QTableWidgetItem('%f' % x)
       elif isinstance(x, float):
           return QtGui.QTableWidgetItem('%f' % x)
       elif isinstance(x, int):
           return QtGui.QTableWidgetItem('%i' % x)
       return QtGui.QTableWidgetItem('')
Beispiel #6
0
class SlitTab:
    def __init__(self, ui, infile=None):
        self.ui = ui
        self.slitlets = Slitlets()
        self.infile = infile
        self.cell = None
        self.rows = None

    def unique(self, seq):
        '''
        return a unique number of rows from the table selection
        '''
        seen = set()
        seen_add = seen.add
        return [x for x in seq if x not in seen and not seen_add(x)]

    def setposition(self):
        '''
        determine the which rows are selected for the deletion on slits
        '''
        self.rows = []
        indexes = self.ui.tableWidgetSlits.selectedIndexes()
        for index in indexes:
            self.rows.append(index.row())
        self.rows = self.unique(self.rows)
        print self.rows

    def clearslittable(self):
        '''
        set all the in_mask flags to 0 and update the slit table
        '''
        rows = self.ui.tableWidgetSlits.rowCount()
        print rows
        self.slitlets.data['inmask_flag'] = 0
        self.updatetabs()
#        self.ui.tableWidgetSlits.clear()
#        for i in range(0,rows):
#            print i
#            self.ui.tableWidgetSlits.removeRow(i)

    def addslitmanually(self):
        '''
        add an empy row to the slit table that the user must fill in manually
        '''
        #        rows = self.ui.tableWidgetSlits.rowCount()
        #        print rows
        #        if rows > 0:
        #            self.ui.tableWidgetSlits.setRowCount(rows+1)
        ##            self.ui.tableWidgetSlits.insertRow(rows+1)
        #            for j in range(len(catcolumn_list)):
        #                item = self.parseItem('')
        #                self.ui.tableWidgetSlits.setItem(rows+1,j,item)
        #        else:
        #            self.ui.tableWidgetSlits.setRowCount(0)
        #            self.ui.tableWidgetSlits.insertRow(0)
        #            for j in range(len(catcolumn_list)):
        #                item = self.parseItem('')
        #                self.ui.tableWidgetSlits.setItem(rows+1,j,item)

        ######### TESTING: ###########
        self.slitlets.add_slitlet()
        self.slitmask.outFoV()
        self.updatetabs()

    def deleteslitmanually(self):
        '''
        set the selected slits inmask_flag to 0, if none were slected, do nothing
        '''

        if len(self.rows) == 0:
            return
        else:
            print self.rows
            for i in self.rows:
                item = self.ui.tableWidgetSlits.item(i, 0)
                name = str(item.text())
                ai = np.where(self.slitlets.data['name'] == name)
                self.slitlets.data[ai[0][0]]['inmask_flag'] = 0
        self.slitlets.update_flags()
        self.updatetabs()
        return

    def addslitletsfromcatalogue(self):
        '''
        if a slit has a priority >=0 add it to the slits table.
        * if slits have been added manually before adding from the catalogue
        the row count is set accordingly
        TODO: add in the FoV checker before loading slits and set the appropriate
        flags
        '''
        slits = np.where((self.slitlets.data['priority'] >= 0) *
                         (self.slitlets.data['fov_flag'] == 1))
        for i in slits[0]:
            self.slitlets.data[i]['inmask_flag'] = 1
        self.slitmask.outFoV_all()
        self.slitmask.find_collisions()
        self.slitlets.update_flags()
        self.updatetabs()

#        rows = self.ui.tableWidgetSlits.rowCount()
#        if rows > 0:
#            self.ui.tableWidgetSlits.setRowCount(rows+1)
#            row = rows+1
#        else:
#            self.ui.tableWidgetSlits.setRowCount(0)
#            row = 0
#
#        for i in slits[0]:
#            self.ui.tableWidgetSlits.insertRow(row)
#            for j in range(len(catcolumn_list)-1):
#                item=self.parseItem(self.slitlets.data[catcolumn_list[j]][i])
#                self.ui.tableWidgetSlits.setItem(row,j,item)
#            row+=1

    def updateslittable(self):
        """Using the slitlet object, update the slit table"""

        # check which entries are in the mask and not reference stars
        inmask = np.where((self.slitlets.data['inmask_flag'] == 1) *
                          (self.slitlets.data['refstar_flag'] == 0))

        #enter the information into the table
        self.ui.tableWidgetSlits.setRowCount(0)
        nobj = 0
        for i in inmask[0]:
            self.ui.tableWidgetSlits.insertRow(nobj)
            for j in range(len(catcolumn_list)):
                item = self.parseItem(self.slitlets.data[catcolumn_list[j]][i])
                self.ui.tableWidgetSlits.blockSignals(True)
                self.ui.tableWidgetSlits.setItem(nobj, j, item)
                self.ui.tableWidgetSlits.blockSignals(False)
            nobj += 1
#        for i in range(self.slitlets.nobjects):
#            if self.slitlets.data['inmask_flag'][i]==1:
#
#                if nobj>self.ui.tableWidgetSlits.rowCount():
#                    self.ui.tableWidgetSlits.insertRow(nobj)
#                for j in range(len(catcolumn_list)-1):
#                    f=catcolumn_list[j]
#                    item=self.parseItem(self.slitlets.data[catcolumn_list[j]][i])
#                    self.ui.tableWidgetSlits.setItem(nobj,j,item)
#            nobj+=1

    def slitchanged(self, x, y):
        """When ever a cell is changed, updated the information about the slit"""
        #identify what slit changed and what attribute of that slit changed
        item = self.ui.tableWidgetSlits.item(x, 0)
        name = str(item.text())
        ai = self.slitlets.findslitlet(name)

        #update the attribute
        item = self.ui.tableWidgetSlits.item(x, y)
        self.slitlets.updatevalue(ai, str(item.text()), catcolumn_list[y])

        #update all the tabs
        self.slitmask.outFoV_row(ai)
        self.slitmask.find_collisions()
        self.slitlets.update_flags()
        self.updatetabs()

    def updatetabs(self):
        """Task designed for overloading"""
        self.updateslittable()
        self.updatecatalogtable()

    def parseItem(self, x):
        """Parse an object so it can be entered into the table"""
        if isinstance(x, str):
            return QtGui.QTableWidgetItem(x)
        elif isinstance(x, numpy.float32):
            return QtGui.QTableWidgetItem('%f' % x)
        elif isinstance(x, float):
            return QtGui.QTableWidgetItem('%f' % x)
        elif isinstance(x, int):
            return QtGui.QTableWidgetItem('%i' % x)
        return QtGui.QTableWidgetItem('')
Beispiel #7
0
class CatalogTab:
    def __init__(self, ui, infile=None):
        self.ui = ui
        self.slitlets = Slitlets()
        self.slitmask = Slimask()
        self.infile = infile

    def getxml(self,infile):
        """Return the xml dom file if infile is either an xml file or an rsmt file"""
        try:
            zip = zipfile.ZipFile(infile,'r')
            zip.extract('Slitmask.xml')
            try:
                dom = minidom.parse('Slitmask.xml')
            except xml.parsers.expat.ExpatError as e:
                raise ReadXMLError(e)

        except zipfile.BadZipfile:
            try:
                dom = minidom.parse(infile)
            except xml.parsers.expat.ExpatError as e:
                raise ReadXMLError(e)
        return dom

    def loadcatalog(self):
        """Locate a file and then enter it into the ui"""

        #launch a file IO dialog
        ldir = os.getcwd()
        infile = QtGui.QFileDialog.getOpenFileName(caption="Open Catalog", directory=ldir)

        #load that file into the catalog
        self.entercatalog(str(infile))
        # set the new mask values on the display
        self.ui.lineEditMain_CenRA.setText(str(self.slitmask.center_ra))
        self.ui.lineEditMain_CenDEC.setText(str(self.slitmask.center_dec))
        self.ui.lineEditMain_PA.setText(str(self.slitmask.position_angle))
        self.ui.lineEditMain_Equinox.setText(str(self.slitmask.equinox))
        
        if self.slitmask.target_name:
           self.ui.lineEditMain_TargetName.setText(self.slitmask.target_name)
        if self.slitmask.mask_name:
           self.ui.lineEditMain_MaskName.setText(self.slitmask.mask_name)
        if self.slitmask.creator:
           self.ui.lineEditInfo_Creator.setText(self.slitmask.creator)
        if self.slitmask.proposer:
           self.ui.lineEditInfo_Proposer.setText(self.slitmask.proposer)
        if self.slitmask.proposal_code:
           self.ui.lineEditInfo_ProposalCode.setText(self.slitmask.proposal_code)

    def entercatalog(self, infile=None, form='short'):
        """Given a catalog, enter it into table in the ui"""
   
        #double check that a file exists and if not, then load it
        self.infile = infile
        if self.infile is None: 
           self.loadcatalog()
           return

        # check whether the input file is a rsmt or xml file. if it is a xml file
        # load the xml slitmask info, else load it as an ascii file
        try:
            self.slitmask.readmaskxml(self.getxml(str(infile)))
        except ReadXMLError:
            #enter the file information into the slit_arr
            self.slitlets.readascii(self.infile, form=form)
            self.slitmask.set_MaskPosition()
        print(self.slitmask.center_ra, self.slitmask.center_dec)
        #check for objects outside the FoV
        self.slitmask.outFoV()
        ### TESTING THE COLLISION CHECKER
        self.slitmask.find_collisions()
        #update the table
        self.updatetabs()



    def updatecatalogtable(self):
        self.slitlets.update_flags()
        rows = self.ui.tableWidgetCat.rowCount()
        for i in range(0,rows):
            self.ui.tableWidgetCat.removeRow(i)

        self.ui.tableWidgetCat.setRowCount(0)
        #enter the information into the table
        for i in range(self.slitlets.nobjects):
            if i > self.ui.tableWidgetCat.rowCount():
                self.ui.tableWidgetCat.insertRow(i-1)
            for j in range(len(catcolumn_list)):
                f = catcolumn_list[j]
                item = self.parseItem(self.slitlets.data[catcolumn_list[j]][i])
                self.ui.tableWidgetCat.setItem(i-1,j,item)

    def updatetabs(self):
       """Task designed for overloading"""
       self.updatecatalogtable()

    def addslitfromcatalog(self):
       """Determine slits elected in the catalog and add them to the catalog"""

       #get the selected items
       sel_list = self.ui.tableWidgetCat.selectedItems()
       print(self.ui.tableWidgetCat.selectedRanges())
       
       #for each item in sel_list, 
       #get the item, and determine the parameters from it 
       #and activite the object
       for selitem in sel_list:
           selitem.row() 
           i = selitem.row()
           stext = self.ui.tableWidgetCat.item(i,0).text()
           sid = self.slitlets.findslitlet(str(stext))
           self.slitlets.addtomask(sid)
       self.updatetabs()
           
        
    def parseItem(self, x):
       """Parse an object so it can be entered into the table"""
       if isinstance(x, str):
           return QtGui.QTableWidgetItem(x)
       elif isinstance(x, np.float32):
           return QtGui.QTableWidgetItem('%f' % x)
       elif isinstance(x, float):
           return QtGui.QTableWidgetItem('%f' % x)
       elif isinstance(x, int):
           return QtGui.QTableWidgetItem('%i' % x)
       return QtGui.QTableWidgetItem('')