Exemple #1
0
def testg_initCustomShape():

    config = confParse.loadSoapyConfig(os.path.join(CONFIG_PATH,
                                                    "sh_8x8.yaml"))

    config.sim.pupilSize = 64
    config.sim.simSize = 66
    mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)
    wfs = WFS.ShackHartmann(config, mask=mask)
    dm = DM.KarhunenLoeve(config, n_dm=1, wfss=[wfs], mask=mask)
    customShape = dm.iMatShapes

    # saving temporary shapes
    fname = os.path.dirname(
        os.path.abspath(__file__)) + '/tmp_CustomDmShapes.fits'
    fits.writeto(fname, customShape, overwrite=True)

    # change size to ensure it tests interpolation
    config.sim.pupilSize = 100
    config.sim.simSize = 104
    mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)
    wfs = WFS.ShackHartmann(config, mask=mask)
    config.dms[1].dmShapesFilename = fname
    dm = DM.CustomShapes(config, n_dm=1, wfss=[wfs], mask=mask)
    # remove temporary shapes
    os.remove(fname)
Exemple #2
0
def make_pupil_mask(mask, n_subap, nx_subap, obs_diam, tel_diam):
    """Generates a SOAPY pupil mask
    - code has been adapted from SOAPY make_mask.py

    Parameters:
        mask (str): must be 'circle'
        nx_subap (int): number of sub-apertures across telescope's pupil.
        obs_diam (float): diameter of central obscuration.
        tel_diam (float): diameter of telescope pupil.

    Returns:
        ndarray: mask of SHWFS sub-apertures within the telescope's pupil."""

    if mask == "circle":
        pupil_mask = aotools.circle(nx_subap / 2., nx_subap)
        if obs_diam != None:
            pupil_mask -= aotools.circle(
                nx_subap * ((obs_diam / tel_diam) / 2.), nx_subap)

    else:
        raise Exception(
            'Only circlular pupil masks have been integrated (sorry).')

    if n_subap[0] != int(numpy.sum(pupil_mask)):
        raise Exception(
            'Error in the number of sub-apertures within pupil mask.')

    return pupil_mask.astype(int)
def test_slopecovmat_makecovmat_uneven():
    threads = 1

    n_wfs = 3
    telescope_diameter = 8.
    nx_subaps = 10

    n_layers = 3
    layer_altitudes = numpy.linspace(0, 20000, n_layers)
    layer_r0s = [1] * n_layers
    layer_L0s = [25.] * n_layers

    asterism_radius = 10
    # What if all WFSs don't have the same number of subaps?
    pupil_masks = [aotools.circle(4.5, nx_subaps), aotools.circle(nx_subaps / 2., nx_subaps), aotools.circle(nx_subaps / 2., nx_subaps)]
    subap_diameters = [telescope_diameter / nx_subaps] * n_wfs
    gs_altitudes = [90000] * n_wfs
    gs_positions = [
        [asterism_radius, 0],
        [numpy.sin(numpy.pi / 3.) * asterism_radius, numpy.cos(numpy.pi / 3.) * asterism_radius],
        [numpy.sin(numpy.pi / 3.) * asterism_radius, -numpy.cos(numpy.pi / 3.) * asterism_radius],
        [-numpy.sin(numpy.pi / 3.) * asterism_radius, numpy.cos(numpy.pi / 3.) * asterism_radius],
        [-numpy.sin(numpy.pi / 3.) * asterism_radius, -numpy.cos(numpy.pi / 3.) * asterism_radius],
        [-asterism_radius, 0]]
    wfs_magnifications = [1.] * n_wfs
    pupil_offsets = [[0, 0]] * n_wfs
    wfs_rotations = [0] * n_wfs
    wfs_wavelengths = [550e-9] * n_wfs

    cov_mat = aotools.CovarianceMatrix(n_wfs, pupil_masks, telescope_diameter, subap_diameters, gs_altitudes, gs_positions,
                                    wfs_wavelengths,
                                    n_layers, layer_altitudes, layer_r0s, layer_L0s, threads)

    covariance_matrix = cov_mat.make_covariance_matrix()
Exemple #4
0
def test_slopecovmat_makecovmat_uneven():
    threads = 1

    n_wfs = 3
    telescope_diameter = 8.
    nx_subaps = 10

    n_layers = 3
    layer_altitudes = numpy.linspace(0, 20000, n_layers)
    layer_r0s = [1] * n_layers
    layer_L0s = [25.] * n_layers

    asterism_radius = 10
    # What if all WFSs don't have the same number of subaps?
    pupil_masks = [
        aotools.circle(4.5, nx_subaps),
        aotools.circle(nx_subaps / 2., nx_subaps),
        aotools.circle(nx_subaps / 2., nx_subaps)
    ]
    subap_diameters = [telescope_diameter / nx_subaps] * n_wfs
    gs_altitudes = [90000] * n_wfs
    gs_positions = [[asterism_radius, 0],
                    [
                        numpy.sin(numpy.pi / 3.) * asterism_radius,
                        numpy.cos(numpy.pi / 3.) * asterism_radius
                    ],
                    [
                        numpy.sin(numpy.pi / 3.) * asterism_radius,
                        -numpy.cos(numpy.pi / 3.) * asterism_radius
                    ],
                    [
                        -numpy.sin(numpy.pi / 3.) * asterism_radius,
                        numpy.cos(numpy.pi / 3.) * asterism_radius
                    ],
                    [
                        -numpy.sin(numpy.pi / 3.) * asterism_radius,
                        -numpy.cos(numpy.pi / 3.) * asterism_radius
                    ], [-asterism_radius, 0]]
    wfs_magnifications = [1.] * n_wfs
    pupil_offsets = [[0, 0]] * n_wfs
    wfs_rotations = [0] * n_wfs
    wfs_wavelengths = [550e-9] * n_wfs

    cov_mat = aotools.CovarianceMatrix(n_wfs, pupil_masks, telescope_diameter,
                                       subap_diameters, gs_altitudes,
                                       gs_positions, wfs_wavelengths, n_layers,
                                       layer_altitudes, layer_r0s, layer_L0s,
                                       threads)

    covariance_matrix = cov_mat.make_covariance_matrix()
def test_chop_subaps_mask_threads():
    """
    Tests that the numba routing chops phase into sub-apertures in the same way
    as using numpy indices
    Runs with multiple threads many times to detectect potential intermittant errors
    """
    nx_phase = 12
    nx_subap_size = 3
    nx_subaps = nx_phase // nx_subap_size

    subap_array = numpy.zeros((nx_subaps * nx_subaps, nx_subap_size,
                               nx_subap_size)).astype("complex64")
    numpy_subap_array = subap_array.copy()

    mask = aotools.circle(nx_phase / 2., nx_phase)

    x_coords, y_coords = numpy.meshgrid(
        numpy.arange(0, nx_phase, nx_subap_size),
        numpy.arange(0, nx_phase, nx_subap_size))
    subap_coords = numpy.array([y_coords.flatten(), x_coords.flatten()]).T

    for i in range(50):
        phase = (numpy.random.random(
            (nx_phase, nx_phase)) + 1j * numpy.random.random(
                (nx_phase, nx_phase))).astype("complex64")

        numpy_chop(phase, subap_coords, nx_subap_size, numpy_subap_array, mask)
        thread_pool = numbalib.ThreadPool(1)
        numbalib.wfs.chop_subaps_mask_pool(phase, subap_coords, nx_subap_size,
                                           subap_array, mask, thread_pool)

        assert numpy.array_equal(numpy_subap_array, subap_array)
Exemple #6
0
def test_chop_subaps_mask():
    """
    Tests that the numba routing chops phase into sub-apertures in the same way
    as using numpy indices
    """
    nx_phase = 12
    nx_subap_size = 3
    nx_subaps = nx_phase // nx_subap_size

    phase = (numpy.random.random(
        (nx_phase, nx_phase)) + 1j * numpy.random.random(
            (nx_phase, nx_phase))).astype("complex64")
    subap_array = numpy.zeros((nx_subaps * nx_subaps, nx_subap_size,
                               nx_subap_size)).astype("complex64")
    numpy_subap_array = subap_array.copy()

    mask = aotools.circle(nx_phase / 2., nx_phase)

    x_coords, y_coords = numpy.meshgrid(
        numpy.arange(0, nx_phase, nx_subap_size),
        numpy.arange(0, nx_phase, nx_subap_size))
    subap_coords = numpy.array([x_coords.flatten(), y_coords.flatten()]).T

    numpy_chop(phase, subap_coords, nx_subap_size, numpy_subap_array, mask)
    numbalib.wfslib.chop_subaps_mask(phase, subap_coords, nx_subap_size,
                                     subap_array, mask)
    assert numpy.array_equal(numpy_subap_array, subap_array)
Exemple #7
0
    def testd_LegacySHWfsFrame(self):
        config = confParse.loadSoapyConfig(os.path.join(CONFIG_PATH, "sh_8x8.yaml"))
        mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)

        wfs = WFS.ShackHartmannLegacy(config, mask=mask)

        wfs.frame(numpy.zeros((config.atmos.scrnNo, config.sim.simSize, config.sim.simSize)))
Exemple #8
0
    def testd_initPhysLgs(self):
        config = confParse.loadSoapyConfig(os.path.join(CONFIG_PATH, "sh_8x8_lgs-uplink.yaml"))
        config.wfss[1].lgs.propagationMode = "Physical"

        mask = aotools.circle(config.sim.pupilSize/2., config.sim.simSize)

        lgs = LGS.LGS_Physical(config.wfss[1], config)
Exemple #9
0
    def calcInitParams(self):
        """
        Calculate some useful paramters to be used later
        """
        self.lgsPupilPxls = int(
            round(self.config.pupilDiam * self.simConfig.pxlScale))

        if self.outPxlScale is None:
            self.outPxlScale_m = 1. / self.simConfig.pxlScale
        else:
            # The pixel scale in metres per pixel at the LGS altitude
            self.outPxlScale_m = (self.outPxlScale / 3600.) * (
                numpy.pi / 180.) * self.config.height

        # Get the angular scale in radians of the output array
        self.outPxlScale_rad = self.outPxlScale_m / self.config.height

        # The number of pixels required across the LGS image
        if self.nOutPxls is None:
            self.nOutPxls = self.simConfig.simSize

        # Field of fov of the requested LGS PSF image
        self.fov = (self.nOutPxls * self.outPxlScale_rad) * RAD2ASEC

        # The number of points required to get the correct FOV after the FFT
        fov_rad = self.fov / RAD2ASEC
        self.nFovPxls = int(
            round(fov_rad * self.config.pupilDiam / self.config.wavelength))

        # The mask to apply before geometric FFTing
        self.mask = aotools.circle(self.nFovPxls / 2., self.nFovPxls)

        self.losNOutPxls = self.lgsPupilPxls
        self.losOutPxlScale = self.config.pupilDiam / self.lgsPupilPxls
Exemple #10
0
    def testc_initGradWfs(self):

        config = confParse.loadSoapyConfig(os.path.join(CONFIG_PATH, "sh_8x8.yaml"))
        config.sim.pupilSize = 10*config.wfss[0].nxSubaps
        mask = aotools.circle(config.sim.pupilSize/2., config.sim.simSize)

        wfs = WFS.Gradient(config, mask=mask)
Exemple #11
0
    def __init__ (self, soapy_config, n_dm=0, wfss=None, mask=None):

        # Sort out some required attributes
        self.soapy_config = soapy_config
        self.n_dm = n_dm

        self.simConfig = self.soapy_config.sim
        self.config = self.dmConfig = self.soapy_config.dms[n_dm]

        self.pupil_size = self.soapy_config.sim.pupilSize
        self.sim_size = self.soapy_config.sim.simSize
        self.scrn_size = self.soapy_config.sim.scrnSize
        self.altitude = self.config.altitude
        self.diameter = self.config.diameter
        self.telescope_diameter = self.soapy_config.tel.telDiam

        self.wfss = wfss

        # If supplied use the mask
        if numpy.any(mask):
            self.mask = mask
        # Else we'll just make a circle
        else:
            self.mask = aotools.circle(
                    self.pupil_size/2., self.sim_size,
                    )

        # the number of phase elements at the DM altitude
        self.nx_dm_elements = int(round(self.pupil_size * self.diameter / self.telescope_diameter))
        self.dm_frame = numpy.zeros((self.nx_dm_elements, self.nx_dm_elements))

        # An array of phase screen size to be observed by a line of sight
        self.dm_screen = numpy.zeros((self.scrn_size, self.scrn_size))

        # Coordinate required to fit dm size back into screen
        self.screen_coord = int(round((self.scrn_size - self.nx_dm_elements)/2.))

        self.n_acts = self.getActiveActs()
        self.actCoeffs = numpy.zeros((self.n_acts))

        # Sort out which WFS(s) observes the DM (for iMat making)
        if self.dmConfig.wfs!=None:
            try:
                # Make sure the specifed WFS actually exists
                self.wfss = [wfss[self.dmConfig.wfs]]
                self.wfs = self.wfss[0]
            except KeyError:
                raise KeyError("DM attached to WFS {}, but that WFS is not specifed in config".format(self.dmConfig.wfs))
        else:
            self.wfss = wfss

        logger.info("Making DM Influence Functions...")
        self.makeIMatShapes()

        # If using imatshapes, sclae by imat value
        if hasattr(self, "iMatShapes"):
            self.iMatShapes *= self.config.iMatValue

        # An array of values for each actuator. 1 if actuator is valid, 0 if not
        self._valid_actuators = numpy.ones((self.n_acts))
Exemple #12
0
def test_Piezo_valid_actuators():
    """
    Tests that when you set the "valid actuators", the DM doesn't use actuators marked 'invalid'
    """

    config = confParse.loadSoapyConfig(os.path.join(CONFIG_PATH, "sh_8x8.yaml"))

    mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)

    wfs = WFS.ShackHartmann(config, mask=mask)
    dm = DM.FastPiezo(config, n_dm=1, wfss=[wfs], mask=mask)

    act_coord1 = dm.valid_act_coords[0]
    act_coord_last = dm.valid_act_coords[-1]
    act_coord2 = dm.valid_act_coords[1]

    valid_actuators = numpy.ones(dm.n_acts, dtype=int)
    valid_actuators[0] = valid_actuators[-1] = 0

    dm.valid_actuators = valid_actuators

    assert dm.n_valid_actuators == (dm.n_acts - 2)
    assert not numpy.array_equal(dm.valid_act_coords[0], act_coord1)
    assert not numpy.array_equal(dm.valid_act_coords[-1], act_coord_last)
    assert numpy.array_equal(dm.valid_act_coords[0], act_coord2)
def test_chop_subaps_mask():
    """
    Tests that the numba routing chops phase into sub-apertures in the same way
    as using numpy indices
    """
    nx_phase = 12
    nx_subap_size = 3
    nx_subaps = nx_phase // nx_subap_size

    phase = (numpy.random.random((nx_phase, nx_phase)) 
                + 1j * numpy.random.random((nx_phase, nx_phase))
                ).astype("complex64")
    subap_array = numpy.zeros((nx_subaps * nx_subaps, nx_subap_size, nx_subap_size)).astype("complex64")
    numpy_subap_array = subap_array.copy()

    mask = aotools.circle(nx_phase/2., nx_phase)

    x_coords, y_coords = numpy.meshgrid(
            numpy.arange(0, nx_phase, nx_subap_size),
            numpy.arange(0, nx_phase, nx_subap_size))
    subap_coords = numpy.array([x_coords.flatten(), y_coords.flatten()]).T

    numpy_chop(phase, subap_coords, nx_subap_size, numpy_subap_array, mask)
    thread_pool = numbalib.ThreadPool(1)
    numbalib.wfs.chop_subaps_mask_pool(
            phase, subap_coords, nx_subap_size, subap_array, mask, thread_pool)
    assert numpy.array_equal(numpy_subap_array, subap_array)
Exemple #14
0
    def __init__ (self, soapy_config, n_dm=0, wfss=None, mask=None):

        # Sort out some required attributes
        self.soapy_config = soapy_config
        self.n_dm = n_dm

        self.simConfig = self.soapy_config.sim
        self.config = self.dmConfig = self.soapy_config.dms[n_dm]

        self.pupil_size = self.soapy_config.sim.pupilSize
        self.sim_size = self.soapy_config.sim.simSize
        self.scrn_size = self.soapy_config.sim.scrnSize
        self.altitude = self.config.altitude
        self.diameter = self.config.diameter
        self.telescope_diameter = self.soapy_config.tel.telDiam

        self.wfss = wfss

        # If supplied use the mask
        if numpy.any(mask):
            self.mask = mask
        # Else we'll just make a circle
        else:
            self.mask = aotools.circle(
                    self.pupil_size/2., self.sim_size,
                    )

        # the number of phase elements at the DM altitude
        self.nx_dm_elements = int(round(self.pupil_size * self.diameter / self.telescope_diameter))
        self.dm_frame = numpy.zeros((self.nx_dm_elements, self.nx_dm_elements))

        # An array of phase screen size to be observed by a line of sight
        self.dm_screen = numpy.zeros((self.scrn_size, self.scrn_size))

        # Coordinate required to fit dm size back into screen
        self.screen_coord = int(round((self.scrn_size - self.nx_dm_elements)/2.))

        self.n_acts = self.getActiveActs()
        self.actCoeffs = numpy.zeros((self.n_acts))

        # Sort out which WFS(s) observes the DM (for iMat making)
        if self.dmConfig.wfs!=None:
            try:
                # Make sure the specifed WFS actually exists
                self.wfss = [wfss[self.dmConfig.wfs]]
                self.wfs = self.wfss[0]
            except KeyError:
                raise KeyError("DM attached to WFS {}, but that WFS is not specifed in config".format(self.dmConfig.wfs))
        else:
            self.wfss = wfss

        logger.info("Making DM Influence Functions...")
        self.makeIMatShapes()

        # If using imatshapes, sclae by imat value
        if hasattr(self, "iMatShapes"):
            self.iMatShapes *= self.config.iMatValue
            
        # An array of values for each actuator. 1 if actuator is valid, 0 if not
        self._valid_actuators = numpy.ones((self.n_acts))
Exemple #15
0
def test_findActiveSubaps_with_returnFill():
    subapertures = 10
    mask = circle(4, 10)
    threshold = .6
    active_subapertures, fill_factors = wfs.findActiveSubaps(subapertures, mask, threshold, returnFill=True)
    assert active_subapertures.shape == (52, 2)
    assert len(fill_factors) == 52
def updateAnimation(f, axarr, error, phase, phaseEst, psf, timer):

    f.suptitle('Algorithm time: {0:.5}s'.format(timer))
    cmap = plt.cm.jet
    error = np.array(error)
    im1 = axarr[0, 0].plot(error[:, 1], linewidth=2.5)
    axarr[0, 0].grid(color='lightgrey', linestyle='--')
    axarr[0, 0].set_title("Wavefront error")
    axarr[0, 0].set_xlabel('iterations')
    axarr[0, 0].set_ylabel('RMSE')
    im2 = axarr[0, 1].imshow(psf**(1/3), cmap=cmap)
    cb2 = plt.colorbar(im2, ax=axarr[0, 1], fraction=0.046)
    axarr[0, 1].set_title("Point Spread function (strehl={0:.5f})".format(utils.strehl(phase-phaseEst)))
    axarr[0, 1].set_axis_off()
    mask=aotools.circle(64, 128).astype(np.float64)
    phase[mask<0.1]=None
    phaseEst[mask<0.1]=None
    im3 = axarr[1, 0].imshow(phase, cmap=cmap)
    im3.set_clim(-np.pi,np.pi)
    cb3 = plt.colorbar(im3, ax=axarr[1, 0], fraction=0.046)
    axarr[1, 0].set_title("Exact Phase")
    axarr[1, 0].set_axis_off()
    im4 = axarr[1, 1].imshow(phaseEst, cmap=cmap)
    im4.set_clim(-np.pi, np.pi)
    axarr[1, 1].set_title("Recovered phase")
    axarr[1, 1].set_axis_off()
    cb4 = plt.colorbar(im4, ax=axarr[1, 1], fraction=0.046)
    plt.pause(1e-5)
    axarr[0, 0].cla()
    cb2.remove()
    cb3.remove()
    cb4.remove()
    phase[mask<0.1]=0
    phaseEst[mask<0.1]=0
Exemple #17
0
    def testa_initLgs(self):

        config = confParse.loadSoapyConfig(os.path.join(CONFIG_PATH, "sh_8x8_lgs-uplink.yaml"))

        mask = aotools.circle(config.sim.pupilSize/2., config.sim.simSize)

        lgs = LGS.LGS(config.wfss[1], config)
Exemple #18
0
    def testc_initLegacySHWfs(self):
        config = confParse.loadSoapyConfig(
            os.path.join(CONFIG_PATH, "sh_8x8.yaml"))

        mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)

        wfs = WFS.ShackHartmannLegacy(config, mask=mask)
def test_chop_subaps_mask_threads():
    """
    Tests that the numba routing chops phase into sub-apertures in the same way
    as using numpy indices
    Runs with multiple threads many times to detectect potential intermittant errors
    """
    nx_phase = 12
    nx_subap_size = 3
    nx_subaps = nx_phase // nx_subap_size

    subap_array = numpy.zeros((nx_subaps * nx_subaps, nx_subap_size, nx_subap_size)).astype("complex64")
    numpy_subap_array = subap_array.copy()

    mask = aotools.circle(nx_phase/2., nx_phase)

    x_coords, y_coords = numpy.meshgrid(
            numpy.arange(0, nx_phase, nx_subap_size),
            numpy.arange(0, nx_phase, nx_subap_size))
    subap_coords = numpy.array([y_coords.flatten(),x_coords.flatten()]).T


    for i in range(50):
        phase = (numpy.random.random((nx_phase, nx_phase)) 
                + 1j * numpy.random.random((nx_phase, nx_phase))
                ).astype("complex64")

        numpy_chop(phase, subap_coords, nx_subap_size, numpy_subap_array, mask)
        thread_pool = numbalib.ThreadPool(1)
        numbalib.wfs.chop_subaps_mask_pool(
                phase, subap_coords, nx_subap_size, subap_array, mask, thread_pool)

        assert numpy.array_equal(numpy_subap_array, subap_array)
Exemple #20
0
    def testa_initWfs(self):

        config = confParse.loadSoapyConfig(os.path.join(CONFIG_PATH, "sh_8x8.yaml"))

        mask = aotools.circle(config.sim.pupilSize/2., config.sim.simSize)

        wfs = WFS.WFS(config, mask=mask)
Exemple #21
0
def testa_initDM():

    config = confParse.loadSoapyConfig(os.path.join(CONFIG_PATH, "sh_8x8.yaml"))

    mask = aotools.circle(config.sim.pupilSize/2., config.sim.simSize)

    wfs = WFS.ShackHartmann(config, mask=mask)
    dm = DM.DM(config, wfss=[wfs], mask=mask)
Exemple #22
0
    def testd_initPhysLgs(self):
        config = confParse.loadSoapyConfig(
            os.path.join(CONFIG_PATH, "sh_8x8_lgs-uplink.yaml"))
        config.wfss[1].lgs.propagationMode = "Physical"

        mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)

        lgs = LGS.LGS_Physical(config.wfss[1], config)
Exemple #23
0
    def testa_initLgs(self):

        config = confParse.loadSoapyConfig(
            os.path.join(CONFIG_PATH, "sh_8x8_lgs-uplink.yaml"))

        mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)

        lgs = LGS.LGS(config.wfss[1], config)
Exemple #24
0
    def testc_geoLgsPsf(self):
        config = confParse.loadSoapyConfig(os.path.join(CONFIG_PATH, "sh_8x8_lgs-uplink.yaml"))

        mask = aotools.circle(config.sim.pupilSize/2., config.sim.simSize)
        config.wfss[1].lgs.propagationMode = "Geometric"
        lgs = LGS.LGS_Geometric(config.wfss[1], config)
        psf = lgs.getLgsPsf(
                   numpy.zeros((config.atmos.scrnNo, config.sim.simSize, config.sim.simSize)))
Exemple #25
0
    def testa_initWfs(self):

        config = confParse.loadSoapyConfig(
            os.path.join(CONFIG_PATH, "sh_8x8.yaml"))

        mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)

        wfs = WFS.WFS(config, mask=mask)
Exemple #26
0
    def testc_initGradWfs(self):

        config = confParse.loadSoapyConfig(
            os.path.join(CONFIG_PATH, "sh_8x8.yaml"))
        config.sim.pupilSize = 10 * config.wfss[0].nxSubaps
        mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)

        wfs = WFS.Gradient(config, mask=mask)
Exemple #27
0
    def testd_SHWfsFrame(self):
        config = confParse.loadSoapyConfig(
            os.path.join(CONFIG_PATH, "sh_8x8.yaml"))
        mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)

        wfs = WFS.ShackHartmann(config, mask=mask)

        wfs.frame(numpy.zeros((config.sim.simSize, config.sim.simSize)))
Exemple #28
0
    def testb_wfsFrame(self):
        config = confParse.loadSoapyConfig(os.path.join(CONFIG_PATH, "sh_8x8.yaml"))

        mask = aotools.circle(config.sim.pupilSize/2., config.sim.simSize)

        wfs = WFS.WFS(config, mask=mask)

        wfs.frame(numpy.zeros((config.sim.simSize, config.sim.simSize)))
Exemple #29
0
    def test_fibreInit(self):

        config = confParse.loadSoapyConfig(
            os.path.join(CONFIG_PATH, "sh_8x8.yaml"))

        mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)

        sci = SCI.singleModeFibre(config, 0, mask)
Exemple #30
0
    def test_sciInit(self):

        config = confParse.loadSoapyConfig(
            os.path.join(CONFIG_PATH, "sh_8x8.yaml"))

        mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)

        sci = scienceinstrument.PSFCamera(config, 0, mask)
Exemple #31
0
    def loadConfig(self):
        """
        Load the Soapy config file
        """
        self.config = confParse.YAML_Configurator(self.configfile)
        self.config.loadSimParams()

        self.mask = aotools.circle(
                self.config.sim.pupilSize/2., self.config.sim.simSize)
Exemple #32
0
    def teste_physLgsPsf(self):
        config = confParse.loadSoapyConfig(os.path.join(CONFIG_PATH, "sh_8x8_lgs-uplink.yaml"))

        config.wfss[1].lgs.propagationMode = "Physical"
        mask = aotools.circle(config.sim.pupilSize/2., config.sim.simSize)

        lgs = LGS.LGS_Physical(config.wfss[1], config, nOutPxls=10)
        psf = lgs.getLgsPsf(
                numpy.zeros((config.atmos.scrnNo, config.sim.simSize, config.sim.simSize)))
Exemple #33
0
    def testd_GradWfsFrame(self):
        config = confParse.loadSoapyConfig(os.path.join(CONFIG_PATH, "sh_8x8.yaml"))
        config.sim.pupilSize = 10*config.wfss[0].nxSubaps

        mask = aotools.circle(config.sim.pupilSize/2., config.sim.simSize)

        wfs = WFS.Gradient(config, mask=mask)

        wfs.frame(numpy.zeros((config.sim.simSize, config.sim.simSize)))
Exemple #34
0
    def test_PhysWfs(self):

        config = confParse.loadSoapyConfig(os.path.join(CONFIG_PATH, "sh_8x8.yaml"))
        config.wfss[0].propagationMode = "Physical"

        mask = aotools.circle(config.sim.pupilSize/2., config.sim.simSize)

        wfs = WFS.WFS(config, mask=mask)

        wfs.frame(numpy.zeros((config.atmos.scrnNo, config.sim.scrnSize, config.sim.scrnSize)))
Exemple #35
0
    def testd_GradWfsFrame(self):
        config = confParse.loadSoapyConfig(
            os.path.join(CONFIG_PATH, "sh_8x8.yaml"))
        config.sim.pupilSize = 10 * config.wfss[0].nxSubaps

        mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)

        wfs = WFS.Gradient(config, mask=mask)

        wfs.frame(numpy.zeros((config.sim.simSize, config.sim.simSize)))
Exemple #36
0
    def testc_geoLgsPsf(self):
        config = confParse.loadSoapyConfig(
            os.path.join(CONFIG_PATH, "sh_8x8_lgs-uplink.yaml"))

        mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)
        config.wfss[1].lgs.propagationMode = "Geometric"
        lgs = LGS.LGS_Geometric(config.wfss[1], config)
        psf = lgs.getLgsPsf(
            numpy.zeros(
                (config.atmos.scrnNo, config.sim.simSize, config.sim.simSize)))
Exemple #37
0
    def test_fibreFrame(self):
        config = confParse.loadSoapyConfig(
            os.path.join(CONFIG_PATH, "sh_8x8.yaml"))

        mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)

        sci = SCI.singleModeFibre(config, 0, mask)
        sci.frame(
            numpy.ones((config.atmos.scrnNo, config.sim.scrnSize,
                        config.sim.scrnSize)))
Exemple #38
0
def make_mask(config):
    """
    Generates a Soapy pupil mask

    Parameters:
        config (SoapyConfig): Config object describing Soapy simulation

    Returns:
        ndarray: 2-d pupil mask
    """
    if config.tel.mask == "circle":
        mask = aotools.circle(config.sim.pupilSize / 2.,
                                  config.sim.simSize)
        if config.tel.obsDiam != None:
            mask -= aotools.circle(
                config.tel.obsDiam * config.sim.pxlScale / 2.,
                config.sim.simSize
            )

    elif isinstance(config.tel.mask, str):
        maskHDUList = fits.open(config.tel.mask)
        mask = maskHDUList[0].data.copy()
        maskHDUList.close()
        logger.info('load mask "{}", of size: {}'.format(config.tel.mask, mask.shape))

        if not numpy.array_equal(mask.shape, (config.sim.pupilSize,) * 2):
            # interpolate mask to pupilSize if not that size already
            mask = numpy.round(interp.zoom(mask, config.sim.pupilSize))

    else:
        mask = config.tel.mask.copy()

    # Check its size is compatible. If its the pupil size, pad to sim size
    if (not numpy.array_equal(mask.shape, (config.sim.pupilSize,)*2)
            and not numpy.array_equal(mask.shape, (config.sim.simSize,)*2) ):
        raise ValueError("Mask Shape {} not compatible. Should be either `pupilSize` or `simSize`".format(mask.shape))

    if mask.shape != (config.sim.simSize, )*2:
        mask = numpy.pad(
                mask, config.sim.simPad, mode="constant")

    return mask
Exemple #39
0
def make_mask(config):
    """
    Generates a Soapy pupil mask

    Parameters:
        config (SoapyConfig): Config object describing Soapy simulation

    Returns:
        ndarray: 2-d pupil mask
    """
    if config.tel.mask == "circle":
        mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)
        if config.tel.obsDiam != None:
            mask -= aotools.circle(
                config.tel.obsDiam * config.sim.pxlScale / 2.,
                config.sim.simSize)

    elif isinstance(config.tel.mask, str):
        maskHDUList = fits.open(config.tel.mask)
        mask = maskHDUList[0].data.copy()
        maskHDUList.close()
        logger.info('load mask "{}", of size: {}'.format(
            config.tel.mask, mask.shape))

        if not numpy.array_equal(mask.shape, (config.sim.pupilSize, ) * 2):
            # interpolate mask to pupilSize if not that size already
            mask = numpy.round(interp.zoom(mask, config.sim.pupilSize))

    else:
        mask = config.tel.mask.copy()

    # Check its size is compatible. If its the pupil size, pad to sim size
    if (not numpy.array_equal(mask.shape, (config.sim.pupilSize, ) * 2)
            and not numpy.array_equal(mask.shape, (config.sim.simSize, ) * 2)):
        raise ValueError(
            "Mask Shape {} not compatible. Should be either `pupilSize` or `simSize`"
            .format(mask.shape))

    if mask.shape != (config.sim.simSize, ) * 2:
        mask = numpy.pad(mask, config.sim.simPad, mode="constant")

    return mask
Exemple #40
0
    def teste_physLgsPsf(self):
        config = confParse.loadSoapyConfig(
            os.path.join(CONFIG_PATH, "sh_8x8_lgs-uplink.yaml"))

        config.wfss[1].lgs.propagationMode = "Physical"
        mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)

        lgs = LGS.LGS_Physical(config.wfss[1], config, nOutPxls=10)
        psf = lgs.getLgsPsf(
            numpy.zeros(
                (config.atmos.scrnNo, config.sim.simSize, config.sim.simSize)))
Exemple #41
0
    def test_sciFrame(self):
        config = confParse.loadSoapyConfig(
            os.path.join(CONFIG_PATH, "sh_8x8.yaml"))

        mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)

        sci = scienceinstrument.PSFCamera(config, 0, mask)

        sci.frame(
            numpy.ones((config.atmos.scrnNo, config.sim.scrnSize,
                        config.sim.scrnSize)))
def strehl(phase):
    mask = aotools.circle(64, 128)
    N = 0.0
    phase_mean = 0.0
    for i in range(128):
        for j in range(128):
            if (mask[i, j] >= 0.001):
                N += 1
                phase_mean += phase[i, j]
    phase_mean = phase_mean / N
    strehl = np.abs(np.mean(np.exp(1j * (phase - phase_mean))))**2
    return strehl
def test_propagation_conserves_intensity():
    screen = phasescreen.ft_phase_screen(0.16, 512, 4.2 / 512, 100, 0.01)

    # Input E Field
    E = numpy.exp(1j * screen)

    Em = E * circle(150, 512)
    sum1 = (abs(Em) ** 2).sum()
    prop1 = opticalpropagation.angularSpectrum(Em, 500e-9, 4.2 / 512, 4.2 / 512, 10000.)
    sum2 = (abs(prop1) ** 2).sum()

    assert numpy.allclose(sum1, sum2)
Exemple #44
0
def test_slopecovmat_makecovmat_multithreaded():
    threads = 2

    n_wfs = 3
    telescope_diameter = 8.
    nx_subaps = 10

    n_layers = 3
    layer_altitudes = numpy.linspace(0, 20000, n_layers)
    layer_r0s = [1] * n_layers
    layer_L0s = [25.] * n_layers

    asterism_radius = 10

    subap_diameters = [telescope_diameter / nx_subaps] * n_wfs
    pupil_masks = [aotools.circle(nx_subaps / 2., nx_subaps)] * n_wfs
    gs_altitudes = [90000] * n_wfs
    gs_positions = [[asterism_radius, 0],
                    [
                        numpy.sin(numpy.pi / 3.) * asterism_radius,
                        numpy.cos(numpy.pi / 3.) * asterism_radius
                    ],
                    [
                        numpy.sin(numpy.pi / 3.) * asterism_radius,
                        -numpy.cos(numpy.pi / 3.) * asterism_radius
                    ],
                    [
                        -numpy.sin(numpy.pi / 3.) * asterism_radius,
                        numpy.cos(numpy.pi / 3.) * asterism_radius
                    ],
                    [
                        -numpy.sin(numpy.pi / 3.) * asterism_radius,
                        -numpy.cos(numpy.pi / 3.) * asterism_radius
                    ], [-asterism_radius, 0]]
    wfs_magnifications = [1.] * n_wfs
    pupil_offsets = [[0, 0]] * n_wfs
    wfs_rotations = [0] * n_wfs
    wfs_wavelengths = [550e-9] * n_wfs

    cov_mat = aotools.CovarianceMatrix(n_wfs, pupil_masks, telescope_diameter,
                                       subap_diameters, gs_altitudes,
                                       gs_positions, wfs_wavelengths, n_layers,
                                       layer_altitudes, layer_r0s, layer_L0s,
                                       threads)
    covariance_matrix_multithread = cov_mat.make_covariance_matrix()

    # Check consistant with single thread implementation

    cov_mat.threads = 1
    covariance_matrix = cov_mat.make_covariance_matrix()

    assert numpy.array_equal(covariance_matrix, covariance_matrix_multithread)
Exemple #45
0
    def test_sciStrehl(self):
        config = confParse.loadSoapyConfig(
            os.path.join(CONFIG_PATH, "sh_8x8.yaml"))

        mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)

        sci = SCI.PSF(config, 0, mask)

        sci.frame(
            numpy.ones((config.atmos.scrnNo, config.sim.scrnSize,
                        config.sim.scrnSize)))

        self.assertTrue(numpy.allclose(sci.instStrehl, 1.))
Exemple #46
0
    def test_PhysWfs(self):

        config = confParse.loadSoapyConfig(
            os.path.join(CONFIG_PATH, "sh_8x8.yaml"))
        config.wfss[0].propagationMode = "Physical"

        mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)

        wfs = WFS.WFS(config, mask=mask)

        wfs.frame(
            numpy.zeros((config.atmos.scrnNo, config.sim.scrnSize,
                         config.sim.scrnSize)))
Exemple #47
0
    def __init__(
            self, soapy_config, n_wfs=0, mask=None):

        self.soapy_config = soapy_config
        self.config = self.wfsConfig = soapy_config.wfss[n_wfs] # For compatability

        self.lgsConfig = self.config.lgs

        # Sort out some required, static, parameters
        self.pupil_size = self.soapy_config.sim.pupilSize
        self.sim_size = self.soapy_config.sim.simSize
        self.phase_scale = 1./self.soapy_config.sim.pxlScale
        self.sim_pad = self.soapy_config.sim.simPad
        self.screen_size = self.soapy_config.sim.scrnSize
        self.telescope_diameter = self.soapy_config.tel.telDiam
        self.wavelength = self.config.wavelength
        self.threads = self.soapy_config.sim.threads


        # If supplied use the mask
        if numpy.any(mask):
            self.mask = mask
        # Else we'll just make a circle
        else:
            self.mask = aotools.circle(self.pupil_size/2., self.sim_size)

        self.iMat = False

        # Init the line of sight
        self.initLos()

        self.calcInitParams()
        # If GS not at infinity, find meta-pupil radii for each layer
        # if self.config.GSHeight != 0:
        #     self.radii = self.los.findMetaPupilSizes(self.config.GSHeight)
        # else:
        #     self.radii = None

        # Init LGS, FFTs and allocate some data arrays
        self.initFFTs()
        if self.lgsConfig and self.config.lgs:
            self.initLGS()

        self.allocDataArrays()

        self.calcTiltCorrect()
        self.getStatic()

        # base WFS makes no measurements....
        self.n_measurements = 0
Exemple #48
0
    def setMask(self, mask):
        """
        Sets the pupil mask as seen by the WFS.

        This method can be called during a simulation
        """

        # If supplied use the mask
        if numpy.any(mask):
            self.mask = mask
        else:
            self.mask = aotools.circle(
                    self.pupil_size/2., self.sim_size,
                    )
Exemple #49
0
def test_set_valid_actuators():
    """
    Tests that when you set the "valid actuators", the DM computes how many valid actuators there are correctly
    """

    config = confParse.loadSoapyConfig(os.path.join(CONFIG_PATH, "sh_8x8.yaml"))

    mask = aotools.circle(config.sim.pupilSize/2., config.sim.simSize)

    wfs = WFS.ShackHartmann(config, mask=mask)
    dm = DM.DM(config, n_dm=1, wfss=[wfs], mask=mask)

    valid_actuators = numpy.ones(dm.n_acts, dtype=int)
    valid_actuators[0] = valid_actuators[-1] = 0

    dm.valid_actuators = valid_actuators

    assert dm.n_valid_actuators == (dm.n_acts - 2)
def test_slopecovmat_makecovmat_multithreaded():
    threads = 2

    n_wfs = 3
    telescope_diameter = 8.
    nx_subaps = 10

    n_layers = 3
    layer_altitudes = numpy.linspace(0, 20000, n_layers)
    layer_r0s = [1] * n_layers
    layer_L0s = [25.] * n_layers

    asterism_radius = 10

    subap_diameters = [telescope_diameter / nx_subaps] * n_wfs
    pupil_masks = [aotools.circle(nx_subaps / 2., nx_subaps)] * n_wfs
    gs_altitudes = [90000] * n_wfs
    gs_positions = [
        [asterism_radius, 0],
        [numpy.sin(numpy.pi / 3.) * asterism_radius, numpy.cos(numpy.pi / 3.) * asterism_radius],
        [numpy.sin(numpy.pi / 3.) * asterism_radius, -numpy.cos(numpy.pi / 3.) * asterism_radius],
        [-numpy.sin(numpy.pi / 3.) * asterism_radius, numpy.cos(numpy.pi / 3.) * asterism_radius],
        [-numpy.sin(numpy.pi / 3.) * asterism_radius, -numpy.cos(numpy.pi / 3.) * asterism_radius],
        [-asterism_radius, 0]]
    wfs_magnifications = [1.] * n_wfs
    pupil_offsets = [[0, 0]] * n_wfs
    wfs_rotations = [0] * n_wfs
    wfs_wavelengths = [550e-9] * n_wfs

    cov_mat = aotools.CovarianceMatrix(n_wfs, pupil_masks, telescope_diameter, subap_diameters, gs_altitudes, gs_positions,
                                    wfs_wavelengths,
                                    n_layers, layer_altitudes, layer_r0s, layer_L0s, threads)
    covariance_matrix_multithread = cov_mat.make_covariance_matrix()

    # Check consistant with single thread implementation

    cov_mat.threads = 1
    covariance_matrix = cov_mat.make_covariance_matrix()

    assert numpy.array_equal(covariance_matrix, covariance_matrix_multithread)
def test_covtomorecon():
    threads = 1

    n_wfs = 3
    telescope_diameter = 8.
    nx_subaps = 10

    n_layers = 3
    layer_altitudes = numpy.linspace(0, 20000, n_layers)
    layer_r0s = [1] * n_layers
    layer_L0s = [25.] * n_layers

    asterism_radius = 10

    subap_diameters = [telescope_diameter / nx_subaps] * n_wfs
    pupil_masks = [aotools.circle(nx_subaps / 2., nx_subaps)] * n_wfs
    gs_altitudes = [90000] * n_wfs
    gs_positions = [
        [asterism_radius, 0],
        [numpy.sin(numpy.pi / 3.) * asterism_radius, numpy.cos(numpy.pi / 3.) * asterism_radius],
        [numpy.sin(numpy.pi / 3.) * asterism_radius, -numpy.cos(numpy.pi / 3.) * asterism_radius],
        [-numpy.sin(numpy.pi / 3.) * asterism_radius, numpy.cos(numpy.pi / 3.) * asterism_radius],
        [-numpy.sin(numpy.pi / 3.) * asterism_radius, -numpy.cos(numpy.pi / 3.) * asterism_radius],
        [-asterism_radius, 0]]
    wfs_magnifications = [1.] * n_wfs
    pupil_offsets = [[0, 0]] * n_wfs
    wfs_rotations = [0] * n_wfs
    wfs_wavelengths = [550e-9] * n_wfs

    cov_mat = aotools.CovarianceMatrix(n_wfs, pupil_masks, telescope_diameter, subap_diameters, gs_altitudes, gs_positions,
                                    wfs_wavelengths,
                                    n_layers, layer_altitudes, layer_r0s, layer_L0s, threads)

    cov_mat.make_covariance_matrix()

    tomo_recon = cov_mat.make_tomographic_reconstructor()
Exemple #52
0
    def testc_initLegacySHWfs(self):
        config = confParse.loadSoapyConfig(os.path.join(CONFIG_PATH, "sh_8x8.yaml"))

        mask = aotools.circle(config.sim.pupilSize / 2., config.sim.simSize)

        wfs = WFS.ShackHartmannLegacy(config, mask=mask)
    N = 1
    threads = 20

    n_wfs = 6
    telescope_diameter = 8.
    nx_subaps = 10

    n_layers = 3
    layer_altitudes = numpy.linspace(0, 20000, n_layers)
    layer_r0s = [1] * n_layers
    layer_L0s = [25.] * n_layers

    asterism_radius = 10

    subap_diameters = [telescope_diameter / nx_subaps] * n_wfs
    pupil_masks = [aotools.circle(nx_subaps / 2., nx_subaps)] * n_wfs
    gs_altitudes = [90000] * n_wfs
    gs_positions = [
        [asterism_radius, 0],
        [numpy.sin(numpy.pi / 3.) * asterism_radius, numpy.cos(numpy.pi / 3.) * asterism_radius],
        [numpy.sin(numpy.pi / 3.) * asterism_radius, -numpy.cos(numpy.pi / 3.) * asterism_radius],
        [-numpy.sin(numpy.pi / 3.) * asterism_radius, numpy.cos(numpy.pi / 3.) * asterism_radius],
        [-numpy.sin(numpy.pi / 3.) * asterism_radius, -numpy.cos(numpy.pi / 3.) * asterism_radius],
        [-asterism_radius, 0]]
    wfs_magnifications = [1.] * n_wfs
    pupil_offsets = [[0, 0]] * n_wfs
    wfs_rotations = [0] * n_wfs
    wfs_wavelengths = [550e-9] * n_wfs

    t1 = time.time()
    for i in range(N):
def test_photons_per_mag():
    mask = circle(2, 5)
    photons = astronomy.photons_per_mag(5.56, mask, 0.5, 0.3, 10)
    assert type(photons) == float
def test_photons_per_band():
    photons = astronomy.photons_per_band(5.56, circle(2, 5), 0.5, 0.001)
    assert type(photons) == float