Exemple #1
0
def test_hex_aperture():
    """ Ensure the hex aperture used for Zernikes is consistent with the regular
    poppy HexagonAperture
    """

    npix_to_try = [10, 11, 12, 13, 100, 101, 512, 513]

    for npix in npix_to_try:
        assert np.all(optics.HexagonAperture(side=1).sample(npix=npix) - zernike.hex_aperture(
            npix=npix) == 0), "hex_aperture and HexagonAperture outputs differ for npix={}".format(npix)
Exemple #2
0
def test_hex_aperture():
    """ Ensure the hex aperture used for Zernikes is consistent with the regular
    poppy HexagonAperture
    """

    npix_to_try = [10, 11, 12, 13, 100, 101, 512, 513]

    for npix in npix_to_try:
        assert np.all(optics.HexagonAperture(side=1).sample(npix=npix) - zernike.hex_aperture(
            npix=npix) == 0), "hex_aperture and HexagonAperture outputs differ for npix={}".format(npix)
Exemple #3
0
    def __init__(self, nhex=15, narr=200, extrasupportindex=None):
        """
		Input: nzern: number of Noll Zernikes to use in the fit
		Input: narr: the live pupil array size you want to use
		
		Sets up list of poly's and grids & support grids
		Makes coordinate grid for rho and phi and circular support mask
		Calculates 'overlap integrals' (covariance matrix) of the Zernike polynomials on your grid and array size
		Calculates the inverse of this matrix, so it's 'ready to fit' your incoming array
		
		"""
        self.narr = narr
        self.nhex = nhex  # tbd - allowed numbers from Pascal's Triangle sum(n) starting from n=1, viz. n(n+1)/2
        self.grid = (N.indices((self.narr, self.narr), dtype=N.float) -
                     self.narr // 2) / (float(self.narr) * 0.5)
        self.grid_rho = (self.grid**2.0).sum(0)**0.5
        self.grid_phi = N.arctan2(self.grid[0], self.grid[1])
        self.grid_mask = self.grid_rho <= 1
        self.grid_outside = self.grid_rho > 1

        if extrasupportindex is not None:
            self.grid_mask[extrasupportindex] = 0
            self.grid_outside[extrasupportindex] = 1

        # Compute list of explicit Zernike polynomials and keep them around for fitting
        self.hex_list = z.hexike_basis(nterms=self.nhex, npix=self.narr)

        self.hex_list = z.hexike_basis(nterms=self.nhex, npix=self.narr)

        # Force hexikes to be unit standard deviation over hex mask
        for h, hfunc in enumerate(self.hex_list):
            if h > 0:
                self.hex_list[h] = (
                    hfunc / hfunc[self.grid_mask].std()) * self.grid_mask
            else:
                self.hex_list[0] = hfunc * self.grid_mask

        #### Write out a cube of the hexikes in here
        if 0:
            self.stack = N.zeros((self.nhex, self.narr, self.narr))
            for ii in range(len(self.hex_list)):
                self.stack[ii, :, :] = self.hex_list[ii]
        # Calculate covariance between all Zernike polynomials
        self.cov_mat = N.array([[N.sum(hexi * hexj) for hexi in self.hex_list]
                                for hexj in self.hex_list])
        self.grid_mask = z.hex_aperture(npix=self.narr) == 1
        self.grid_outside = self.grid_mask == False
        # Invert covariance matrix using SVD
        self.cov_mat_in = N.linalg.pinv(self.cov_mat)
Exemple #4
0
    def zern_seg(self, segment, vmax=150, unit='nm'):
        """ Show the Zernike terms applied to a given segment"""

        # the actual wavefront is always in units of microns.
        if unit == 'nm':
            scalefact = 1000.
        elif unit =='micron':
            scalefact = 1.0
        else:
            raise ValueError("unknown unit keyword")




        nzerns = 11
        title = "Zernike components for "+segment
        zerns = np.zeros((nzerns))
        if segment+"-decenter" in self.state.keys():
            zerns += self._move(segment, type='decenter', vector=self.state[segment+"-decenter"], return_zernikes=True)
            title += ", displacement=[%.2e, %.2e, %.2e] um" % tuple(self.state[segment+"-decenter"])
        if segment+"-tilt" in self.state.keys():
            zerns += self._move(segment, type='tilt', vector=self.state[segment+"-tilt"], return_zernikes=True)
            title += ", tilts =[%.5f, %.5f, %.5f] urad" % tuple(self.state[segment+"-tilt"])

        _log.info("Zerns: "+str(zerns))
        fig = plt.gcf()
        fig.clf()

        npix=200
        hexap = zernike.hex_aperture(npix)
        hexap[np.where(hexap == 0)] = np.nan
        cmap = matplotlib.cm.jet
        cmap.set_bad('0.5', alpha=0.0)

        for j in np.arange(nzerns)+1:
            ax = fig.add_subplot(3, 4, j, frameon=False, xticks=[], yticks=[])
            # n, m = zernike.noll_indices(j)
            Z = zernike.zernike1(j, npix=npix)
            ax.imshow(Z * zerns[j-1] * hexap*scalefact, vmin=-1*vmax, vmax=vmax, cmap=cmap)
            ax.text(npix*0.95, npix*0.8, "$Z%d$" % (j), fontsize=20, horizontalalignment='right')
            ax.text(npix*0.95, npix*0.1, "%.2e" % (zerns[j-1]), fontsize=15, horizontalalignment='right')

        fig.text(0.5, 0.95, title, horizontalalignment='center', fontsize=15)
        fig.text(0.95, 0.15, 'Segment RMS WFE = %.2f %s ' % (self.rms(segment)*(scalefact/1000), unit), fontsize=10, horizontalalignment='right')
        #fig.text(0.95, 0.05, 'OPDs scaled from %.2e - %.2e um' % (-vmax, vmax), horizontalalignment='right', fontsize=10)
        fig.text(0.95, 0.05, 'OPDs scaled from %.2f - %.2f %s' % (-vmax, vmax, unit), horizontalalignment='right', fontsize=10)

        plt.draw()