Exemplo n.º 1
0
 def test_sincshift(self):
     a = np.zeros((3, 5))
     self.assertEqual(a.shape, util.sincshift(a, 0.1, 0.0).shape)
     self.assertEqual(a.shape, util.sincshift(a, 0.0, 0.1).shape)
     self.assertEqual(a.shape, util.sincshift(a, 0.1, 0.1).shape)
     self.assertEqual(a.shape, util.sincshift2d(a, 0.1, 0.0).shape)
     self.assertEqual(a.shape, util.sincshift2d(a, 0.0, 0.1).shape)
     self.assertEqual(a.shape, util.sincshift2d(a, 0.1, 0.1).shape)
Exemplo n.º 2
0
 def test_sincshift(self):
     a = np.zeros((3,5))
     self.assertEqual(a.shape, util.sincshift(a, 0.1, 0.0).shape)
     self.assertEqual(a.shape, util.sincshift(a, 0.0, 0.1).shape)
     self.assertEqual(a.shape, util.sincshift(a, 0.1, 0.1).shape)
     self.assertEqual(a.shape, util.sincshift2d(a, 0.1, 0.0).shape)
     self.assertEqual(a.shape, util.sincshift2d(a, 0.0, 0.1).shape)
     self.assertEqual(a.shape, util.sincshift2d(a, 0.1, 0.1).shape)
Exemplo n.º 3
0
    def _xypix(self, ispec, wavelength):
        """
        Return xslice, yslice, pix for PSF at spectrum ispec, wavelength
        """
        assert 0 <= ispec < self.nspec
        
        xc, yc = self.xy(ispec, wavelength)
        scale = self._scale  #- shorthand

        #- Calculate offset into CCD pixel
        xoffset = int(xc * scale) % scale
        yoffset = int(yc * scale) % scale

        #- Place high res spot into grid aligned with CCD pixels
        ny, nx = self._spot.shape
        A = np.zeros(shape=(ny+scale, nx+scale))
        A[yoffset:yoffset+ny, xoffset:xoffset+nx] = self._spot
        ccdpix = rebin_image(A, scale)

        #- Fractional high-res pixel offset
        #- This can be slow; is it really necessary?
        dxx = ((xc * scale) % scale - xoffset) / scale
        dyy = ((yc * scale) % scale - yoffset) / scale
        ccdpix = sincshift(ccdpix, dxx, dyy)

        #- sinc shift can cause negative ringing, so clip and re-normalize
        ccdpix = ccdpix.clip(0)
        ccdpix /= np.sum(ccdpix)

        #- Find where the [0,0] pixel goes on the CCD 
        xccd = int(xc - ccdpix.shape[1]/2 + 1)
        yccd = int(yc - ccdpix.shape[0]/2 + 1)

        xx = slice(xccd, xccd+ccdpix.shape[1])
        yy = slice(yccd, yccd+ccdpix.shape[0])

        return xx, yy, ccdpix
Exemplo n.º 4
0
    def _xypix(self, ispec, wavelength):
        """
        Return xslice, yslice, pix for PSF at spectrum ispec, wavelength
        """
        assert 0 <= ispec < self.nspec

        xc, yc = self.xy(ispec, wavelength)
        scale = self._scale  #- shorthand

        #- Calculate offset into CCD pixel
        xoffset = int(xc * scale) % scale
        yoffset = int(yc * scale) % scale

        #- Place high res spot into grid aligned with CCD pixels
        ny, nx = self._spot.shape
        A = np.zeros(shape=(ny + scale, nx + scale))
        A[yoffset:yoffset + ny, xoffset:xoffset + nx] = self._spot
        ccdpix = rebin_image(A, scale)

        #- Fractional high-res pixel offset
        #- This can be slow; is it really necessary?
        dxx = ((xc * scale) % scale - xoffset) / scale
        dyy = ((yc * scale) % scale - yoffset) / scale
        ccdpix = sincshift(ccdpix, dxx, dyy)

        #- sinc shift can cause negative ringing, so clip and re-normalize
        ccdpix = ccdpix.clip(0)
        ccdpix /= np.sum(ccdpix)

        #- Find where the [0,0] pixel goes on the CCD
        xccd = int(xc - ccdpix.shape[1] // 2 + 1)
        yccd = int(yc - ccdpix.shape[0] // 2 + 1)

        xx = slice(xccd, xccd + ccdpix.shape[1])
        yy = slice(yccd, yccd + ccdpix.shape[0])

        return xx, yy, ccdpix
Exemplo n.º 5
0
    def _xypix(self, ispec, wavelength, ispec_cache=None, iwave_cache=None):
        """
        Evaluate PSF for a given spectrum and wavelength
        
        returns xslice, yslice, pixels[yslice, xslice]
        """
        #- Get fiber group and scaling factors for this spectrum
        igroup = self.xyscale['IGROUP'][ispec]
        x0     = self.xyscale['X0'][ispec]
        xscale = self.xyscale['XSCALE'][ispec]
        y0     = self.xyscale['Y0'][ispec]
        yscale = self.xyscale['YSCALE'][ispec]
        
        #- Get x and y centroid
        x, y = self.xy(ispec, wavelength)
        
        #- Rescale units
        xx = xscale * (x - x0)
        yy = yscale * (y - y0)
        
        #- Generate PSF image at (x,y)
        psfimage = np.zeros(self.psfimage.shape[2:4])
        for i in range(self.psfimage.shape[1]):
            nx = self.nexp['XEXP'][i]
            ny = self.nexp['YEXP'][i]
            psfimage += xx**nx * yy**ny * self.psfimage[igroup, i]
                                
        #- Sinc Interpolate
        dx = x - int(round(x))
        dy = y - int(round(y))
        psfimage = sincshift(psfimage, dx, dy)
        
        #- Check boundaries
        ny, nx = psfimage.shape
        ix = int(round(x))
        iy = int(round(y))
        
        xmin = max(0, ix-nx//2)
        xmax = min(self.npix_x, ix+nx//2+1)
        ymin = max(0, iy-ny//2)
        ymax = min(self.npix_y, iy+ny//2+1)
                
        if ix < nx//2:
            psfimage = psfimage[:, nx//2-ix:]
        if iy < ny//2:
            psfimage = psfimage[ny//2-iy:, :]
        
        if ix+nx//2+1 > self.npix_x:
            dx = self.npix_x - (ix+nx//2+1)
            psfimage = psfimage[:, :dx]
            
        if iy+ny//2+1 > self.npix_y:
            dy = self.npix_y - (iy+ny//2+1)
            psfimage = psfimage[:dy, :]
        
        xslice = slice(xmin, xmax)
        yslice = slice(ymin, ymax)

        #- Clip negative values
        psfimage[psfimage<0] = 0.0

        #- Normalize integral to 1.0
        psfimage /= psfimage.sum()
        
        assert xslice.stop-xslice.start == psfimage.shape[1]
        assert yslice.stop-yslice.start == psfimage.shape[0]

        return xslice, yslice, psfimage
Exemplo n.º 6
0
    def _xypix(self, ispec, wavelength):
        """
        Evaluate PSF for a given spectrum and wavelength
        
        returns xslice, yslice, pixels[yslice, xslice]
        """
        #- Get fiber group and scaling factors for this spectrum
        igroup = self.xyscale['IGROUP'][ispec]
        x0 = self.xyscale['X0'][ispec]
        xscale = self.xyscale['XSCALE'][ispec]
        y0 = self.xyscale['Y0'][ispec]
        yscale = self.xyscale['YSCALE'][ispec]

        #- Get x and y centroid
        x, y = self.xy(ispec, wavelength)

        #- Rescale units
        xx = xscale * (x - x0)
        yy = yscale * (y - y0)

        #- Generate PSF image at (x,y)
        psfimage = np.zeros(self.psfimage.shape[2:4])
        for i in range(self.psfimage.shape[1]):
            nx = self.nexp['XEXP'][i]
            ny = self.nexp['YEXP'][i]
            psfimage += xx**nx * yy**ny * self.psfimage[igroup, i]

        #- Sinc Interpolate
        dx = x - int(round(x))
        dy = y - int(round(y))
        psfimage = sincshift(psfimage, dx, dy)

        #- Check boundaries
        ny, nx = psfimage.shape
        ix = int(round(x))
        iy = int(round(y))

        xmin = max(0, ix - nx // 2)
        xmax = min(self.npix_x, ix + nx // 2 + 1)
        ymin = max(0, iy - ny // 2)
        ymax = min(self.npix_y, iy + ny // 2 + 1)

        if ix < nx // 2:
            psfimage = psfimage[:, nx // 2 - ix:]
        if iy < ny // 2:
            psfimage = psfimage[ny // 2 - iy:, :]

        if ix + nx // 2 + 1 > self.npix_x:
            dx = self.npix_x - (ix + nx // 2 + 1)
            psfimage = psfimage[:, :dx]

        if iy + ny // 2 + 1 > self.npix_y:
            dy = self.npix_y - (iy + ny // 2 + 1)
            psfimage = psfimage[:dy, :]

        xslice = slice(xmin, xmax)
        yslice = slice(ymin, ymax)

        #- Clip negative values
        psfimage[psfimage < 0] = 0.0

        #- Normalize integral to 1.0
        psfimage /= psfimage.sum()

        assert xslice.stop - xslice.start == psfimage.shape[1]
        assert yslice.stop - yslice.start == psfimage.shape[0]

        return xslice, yslice, psfimage