예제 #1
0
def coronagraph(wfo, f_lens, occulter_type, diam):
    
    proper.prop_lens(wfo, f_lens, "coronagraph imaging lens")
    proper.prop_propagate(wfo, f_lens, "occulter")
    
    # occulter sizes are specified here in units of lambda/diameter;
    # convert lambda/diam to radians then to meters
    lamda = proper.prop_get_wavelength(wfo)
    occrad = 4.                           # occulter radius in lam/D
    occrad_rad = occrad * lamda / diam    # occulter radius in radians
    dx_m = proper.prop_get_sampling(wfo)
    dx_rad = proper.prop_get_sampling_radians(wfo)    
    occrad_m = occrad_rad * dx_m / dx_rad  # occulter radius in meters

    plt.figure(figsize=(12,8))
        
    if occulter_type == "GAUSSIAN":
        r = proper.prop_radius(wfo)
        h = np.sqrt(-0.5 * occrad_m**2 / np.log(1 - np.sqrt(0.5)))
        gauss_spot = 1 - np.exp(-0.5 * (r/h)**2)
        proper.prop_multiply(wfo, gauss_spot)
        plt.suptitle("Gaussian spot", fontsize = 18)
    elif occulter_type == "SOLID":
        proper.prop_circular_obscuration(wfo, occrad_m)
        plt.suptitle("Solid spot", fontsize = 18)
    elif occulter_type == "8TH_ORDER":
        proper.prop_8th_order_mask(wfo, occrad, CIRCULAR = True)
        plt.suptitle("8th order band limited spot", fontsize = 18)
        
    # After occulter
    plt.subplot(1,2,1)
    plt.imshow(np.sqrt(proper.prop_get_amplitude(wfo)), origin = "lower", cmap = plt.cm.gray)
    plt.text(200, 10, "After Occulter", color = "w")
        
    proper.prop_propagate(wfo, f_lens, "pupil reimaging lens")  
    proper.prop_lens(wfo, f_lens, "pupil reimaging lens")
    
    proper.prop_propagate(wfo, 2*f_lens, "lyot stop")

    plt.subplot(1,2,2)        
    plt.imshow(proper.prop_get_amplitude(wfo)**0.2, origin = "lower", cmap = plt.cm.gray)
    plt.text(200, 10, "Before Lyot Stop", color = "w")
    plt.show()   
    
    if occulter_type == "GAUSSIAN":
        proper.prop_circular_aperture(wfo, 0.25, NORM = True)
    elif occulter_type == "SOLID":
        proper.prop_circular_aperture(wfo, 0.84, NORM = True)
    elif occulter_type == "8TH_ORDER":
        proper.prop_circular_aperture(wfo, 0.50, NORM = True)
    
    proper.prop_propagate(wfo, f_lens, "reimaging lens")
    proper.prop_lens(wfo, f_lens, "reimaging lens")
    
    proper.prop_propagate(wfo, f_lens, "final focus")
    
    return
예제 #2
0
def add_speckles(wfo, pair=True):
    sys.path.append(tp.FPWFSdir)
    import speckle_killer_v3 as skv3
    # speckle = np.roll(np.roll(wfo.wfarr, loc[0],1),loc[1],0)*I#[92,92]
    # wfo.wfarr = (wfo.wfarr+speckle)
    # if pair:
    #     speckle = np.roll(np.roll(wfo.wfarr, -1*loc[0],1),-1*loc[1],0)*I#[92,92]
    #     wfo.wfarr = (wfo.wfarr+speckle)
    # dm_z = proper.prop_fits_read('dm.fits')
    # tp.diam = 0.1                 # telescope diameter in meters
    configfilename = tp.FPWFSdir + 'speckle_null_config_Rupe.ini'
    configspecfile = tp.FPWFSdir + 'speckle_null_config.spec'
    config = ConfigObj(configfilename, configspec=configspecfile)
    val = Validator()
    check = config.validate(val)

    num_speck = len(tp.speck_locs)
    for s in range(num_speck):
        # in creating speckle object it will measure speckle intensity (in the pupil plane), just assign after
        speck = skv3.speckle(proper.prop_get_amplitude(wfo),
                             tp.speck_locs[s][0], tp.speck_locs[s][1], config)
        # print tp.speck_phases
        # tp.speck_phases = [-np.pi]
        # print tp.speck_phases
        phase = tp.speck_phases[s]
        speck.intensity = tp.speck_peakIs[s]
        dm_z = speck.generate_flatmap(phase)  #*4*I
        # quicklook_im(dm_z, logAmp=False)
        FPWFS.propagate_DM(wfo, tp.f_lens, dm_z)
예제 #3
0
def quicklook_wf(wfo, logAmp=True, show=True):

    after_dm = proper.prop_get_amplitude(wfo)
    phase_afterdm = proper.prop_get_phase(wfo)

    fig = plt.figure(figsize=(14, 10))
    ax1 = plt.subplot2grid((3, 2), (0, 0), rowspan=2)
    ax2 = plt.subplot2grid((3, 2), (0, 1), rowspan=2)
    ax3 = plt.subplot2grid((3, 2), (2, 0))
    ax4 = plt.subplot2grid((3, 2), (2, 1))
    if logAmp:
        ax1.imshow(after_dm, origin='lower', cmap="YlGnBu_r", norm=LogNorm())
    else:
        ax1.imshow(after_dm, origin='lower', cmap="YlGnBu_r")
    ax2.imshow(phase_afterdm, origin='lower',
               cmap="YlGnBu_r")  #, vmin=-0.5, vmax=0.5)

    ax3.plot(after_dm[int(tp.grid_size / 2)])
    ax3.plot(np.sum(np.eye(tp.grid_size) * after_dm, axis=1))

    # plt.plot(np.sum(after_dm,axis=1)/after_dm[128,128])

    ax4.plot(phase_afterdm[int(tp.grid_size / 2)])
    # ax4.plot(np.sum(np.eye(tp.grid_size)*phase_afterdm,axis=1))
    plt.xlim([0, proper.prop_get_gridsize(wfo)])
    fig.set_tight_layout(True)
    if show == True:
        plt.show()
예제 #4
0
 def take_src_return_imagedata(self, wfo, exptime=4):
     1  #print("Warning, using fake pharo simulator!")
     self.i = self.i + 1
     # imdata = np.zeros((1024, 1024))
     # FPWFS.propagate_DM(wfo, f_lens, obj_map)
     # FPWFS.quicklook_wf(wfo)
     # FPWFS.quicklook_wf(wfo)
     return proper.prop_get_amplitude(wfo)
예제 #5
0
파일: lyot_stop.py 프로젝트: ppathak8/HEEPS
def lyot_stop(wf, mode='RAVC', ravc_r=0.6, ls_dRext=0.03, ls_dRint=0.05, 
        ls_dRspi=0.04, spi_width=0.5, spi_angles=[0,60,120], diam_ext=37, 
        diam_int=11, ls_misalign=None, file_app_phase='', file_app_amp='', 
        ngrid=1024, npupil=285, margin=50, get_amp=False, 
        get_phase=False, verbose=False, **conf):

    """Add a Lyot stop, or an APP."""
    
    # case 1: Lyot stop
    if mode in ['CVC', 'RAVC']:
        # LS parameters
        r_obstr = ravc_r if mode in ['RAVC'] else diam_int/diam_ext
        ls_int = r_obstr + ls_dRint
        ls_ext = 1 - ls_dRext
        ls_spi = spi_width/diam_ext + ls_dRspi
        # LS misalignments
        ls_misalign = [0,0,0,0,0,0] if ls_misalign is None else list(ls_misalign)
        dx_amp, dy_amp, dz_amp = ls_misalign[0:3]
        dx_phase, dy_phase, dz_phase = ls_misalign[3:6]
        # create Lyot stop
        proper.prop_circular_aperture(wf, ls_ext, dx_amp, dy_amp, NORM=True)
        if diam_int > 0:
            proper.prop_circular_obscuration(wf, ls_int, dx_amp, dy_amp, NORM=True)
        if spi_width > 0:
            for angle in spi_angles:
                proper.prop_rectangular_obscuration(wf, ls_spi, 2, \
                        dx_amp, dy_amp, ROTATION=angle, NORM=True)
        if verbose is True:
            print('Create Lyot stop')
            print('   ls_int=%3.4f, ls_ext=%3.4f, ls_spi=%3.4f'\
                %(ls_int, ls_ext, ls_spi))
            print('')

    # case 2: APP
    elif mode in ['APP']:
        if verbose is True:
            print('Load APP from files\n')
        # get amplitude and phase data
        APP_amp = fits.getdata(file_app_amp) if os.path.isfile(file_app_amp) \
                else np.ones((npupil, npupil))
        APP_phase = fits.getdata(file_app_phase) if os.path.isfile(file_app_phase) \
                else np.zeros((npupil, npupil))
        # resize to npupil
        APP_amp = impro.resize_img(APP_amp, npupil)
        APP_phase = impro.resize_img(APP_phase, npupil)
        # pad with zeros to match PROPER ngrid
        APP_amp = impro.pad_img(APP_amp, ngrid, 1)
        APP_phase = impro.pad_img(APP_phase, ngrid, 0)
        # multiply the loaded APP
        proper.prop_multiply(wf, APP_amp*np.exp(1j*APP_phase))
    
    # get the LS amplitude and phase for output
    LS_amp = impro.crop_img(proper.prop_get_amplitude(wf), npupil, margin)\
            if get_amp is True else None
    LS_phase = impro.crop_img(proper.prop_get_phase(wf), npupil, margin)\
            if get_phase is True else None
    
    return wf, LS_amp, LS_phase
예제 #6
0
def speckle_killer(wf, phase_map):
    # with open(iop.phase_ideal, 'rb') as handle:
    #     phase_ideal = pickle.load(handle)

    # quicklook_im(phase_map, logAmp=False)

    ijofinterest = skv3.identify_bright_points(proper.prop_get_amplitude(wf),
                                               controlregion)
    xyofinterest = [p[::-1] for p in ijofinterest]
    print(xyofinterest, len(xyofinterest))
    if len(xyofinterest) == 0:
        y = int(np.random.uniform(fp.controlregion[0], fp.controlregion[1]))
        x = int(np.random.uniform(fp.controlregion[2], fp.controlregion[3]))
        xyofinterest = [(y, x)]
    if len(xyofinterest) < fp.max_specks:
        fp.max_specks = len(xyofinterest)
    print(fp.max_specks)
    fps = skv3.filterpoints(xyofinterest,
                            max=fp.max_specks,
                            rad=fp.exclusionzone)
    print(fps)

    null_map = np.zeros((tp.ao_act, tp.ao_act))
    for speck in fps:
        print(speck)
        kvecx, kvecy = DM.convert_pixels_kvecs(speck[0],
                                               speck[1],
                                               tp.grid_size / 2,
                                               tp.grid_size / 2,
                                               angle=0,
                                               lambdaoverd=fp.lod)
        dm_phase = phase_map[speck[1], speck[0]]
        s_amp = proper.prop_get_amplitude(wf)[speck[1], speck[0]] * 5.3

        null_map += -DM.make_speckle_kxy(kvecx, kvecy, s_amp,
                                         dm_phase)  #+s_ideal#- 1.9377
    null_map /= len(fps)

    area_sum = np.sum(proper.prop_get_amplitude(wf) * controlregion)
    print(area_sum)
    with open(iop.measured_var, 'ab') as handle:
        pickle.dump(area_sum, handle, protocol=pickle.HIGHEST_PROTOCOL)

    return null_map
예제 #7
0
파일: amp_phase.py 프로젝트: ppathak8/HEEPS
def imshow_amp(wf, npupil=None, margin=0):

    amp = proper.prop_get_amplitude(wf)
    ngrid = amp.shape[0]
    if npupil is None:
        npupil = ngrid
    start = int((ngrid - npupil + npupil % 2) / 2 - margin)
    start = 0 if start < 0 else start
    end = ngrid - start + npupil % 2
    plt.imshow(amp[start:end, start:end], origin='lower')
예제 #8
0
    def quicklook(self, wf=None, logZ=True, show=True, title=None):
        """
        Produces a figure with an image of amplitude and one of phase as well as 1D slices through these images

        :param wf: optics.Wavefront
        :param logZ: bool logarithmic Z scaling
        :param show: bool display figure now or leave show() to be called by user later on
        :param title: str
        :return:
        """
        if wf == None:
            wf = self.wf_collection[0,0]

        amp_map = proper.prop_get_amplitude(wf)
        phase_map = proper.prop_get_phase(wf)

        fig = plt.figure(figsize=(12, 10))
        ax1 = plt.subplot2grid((1, 2), (0, 0), rowspan=2)  # ((shape of grid to place axis x,y),(location x,y))
        ax2 = plt.subplot2grid((1, 2), (0, 1), rowspan=2)
        # ax3 = plt.subplot2grid((3, 2), (2, 0))
        # ax4 = plt.subplot2grid((3, 2), (2, 1))
        if logZ:
            im1 = ax1.imshow(amp_map, origin='lower', cmap="YlGnBu_r", norm=LogNorm())
        else:
            im1 = ax1.imshow(amp_map, origin='lower', cmap="YlGnBu_r")
        ax1.set_title('Amplitude Map')
        plt.colorbar(im1, ax=ax1)

        im2 = ax2.imshow(phase_map, origin='lower', cmap=sunlight)  # , vmin=-0.5, vmax=0.5)
        ax2.set_title('Phase Map')
        plt.colorbar(im2, ax=ax2)

        # ax3.plot(after_dm[int(sp.grid_size / 2)])
        # ax3.plot(np.sum(np.eye(sp.grid_size) * after_dm, axis=1), label=f'row {int(sp.grid_size / 2)}')
        # ax3.legend()
        #
        # # plt.plot(np.sum(after_dm,axis=1)/after_dm[128,128])
        #
        # ax4.plot(phase_afterdm[int(sp.grid_size / 2)], label=f'row {int(sp.grid_size / 2)}')
        # ax4.legend()
        # # ax4.plot(np.sum(np.eye(ap.grid_size)*phase_afterdm,axis=1))
        # plt.xlim([0, proper.prop_get_gridsize(wf)])
        if not title:
            title = input(f"Always Add A Title\n "
                          f"Please Enter Plane Name:")
            fig.suptitle(f"plane: {title}, lambda: {wf.lamda} m, body: {wf.name}", fontsize=18)
        else:
            fig.suptitle(f"plane: {title}, lambda: {wf.lamda} m, body: {wf.name}", fontsize=18)

        plt.subplots_adjust(top=0.9)

        if show:
            plt.show(block=True)
예제 #9
0
def apodize_pupil(wf):
    phase_map = proper.prop_get_phase(wf)
    amp_map = proper.prop_get_amplitude(wf)
    h, w = wf.wfarr.shape[:2]
    wavelength = wf.lamda
    scale = ap.wvl_range[0] / wavelength
    inds = circular_mask(h, w, radius=scale * 0.95 * h * sp.beam_ratio / 2)  #TO DO remove hardcoded sizing, especially if use is default
    mask = np.zeros_like(phase_map)
    mask[inds] = 1
    smooth_mask = gaussian_filter(mask, 1.5, mode='nearest')  #TO DO remove hardcoded sizing, especially if use is default
    smoothed = phase_map * smooth_mask
    wf.wfarr = proper.prop_shift_center(amp_map * np.cos(smoothed) + 1j * amp_map * np.sin(smoothed))
예제 #10
0
def get_wf(wf, plane, npupil=None, margin=0, savefits=False):

    assert plane in ['amp','phi'], 'plane must be "amp" or "phi"'

    if plane is 'amp':
        img = proper.prop_get_amplitude(wf)
    elif plane is 'phi':
        img = proper.prop_get_phase(wf)
    ngrid = img.shape[0]
    if npupil is None:
        npupil = ngrid
    start = int((ngrid - npupil + npupil%2)/2 - margin)
    start = 0 if start < 0 else start
    end = ngrid - start + npupil%2
    img = img[start:end,start:end]
    if savefits is True:
        fits.writeto('%s_npupil=%s_margin=%s.fits'%(plane, npupil, margin), \
            np.float32(img), overwrite=True)
    
    return img
예제 #11
0
def hardmask_pupil(wf):
    """
    hard-edged circular mask of the pupil plane.

    Masks out the WFS map outside of the beam since the DM modeled by proper can only be a square nxn grid of actuators,
    and thus the influence function surrounding each DM actuator could  be affecting on-beam pixels, even if the
    actuator is acting on off-beam signal. In other words, even if a cornerDM actuator doesn't actuate on the beam,
    if there was non-zero signal in the WFS map, it will try to act on it, and it could 'influence' nearby DM actuators
    that are acting on the beam.

    This hard-edged mask is different from prop_circular_aperture in that it does not anti-alias the edges of the mask
    based on the 'fill factor' of the edge pixels. Instead, it has a boolean mask to zero everything > a fixed radius,
    in this case determined by the grid size and beam ratio of each wavefront passed into it.

    :param wf: a single wavefront
    :return: nothing is returned but the wf passed into it has been masked

    """
    phase_map = proper.prop_get_phase(wf)
    amp_map = proper.prop_get_amplitude(wf)

    # Sizing the Mask
    h, w = wf.wfarr.shape[:2]
    center = (int(w / 2), int(h / 2))
    radius = np.floor(
        sp.grid_size * wf.beam_ratio /
        2)  # Should scale with wavelength if sp.focused_system=False,
    # np.ceil used to oversize map so don't clip the beam
    # Making the Circular Boolean Mask
    Y, X = np.mgrid[:h, :w]
    dist_from_center = np.sqrt((X - center[0])**2 + (Y - center[1])**2)
    inds = dist_from_center <= radius

    # Applying the Mask to the Complex Array
    mask = np.zeros_like(phase_map)
    mask[inds] = 1
    masked = phase_map * mask
    wf.wfarr = proper.prop_shift_center(amp_map * np.cos(masked) +
                                        1j * amp_map * np.sin(masked))
예제 #12
0
    def lyotstop(self, wf, RAVC=None, APP=None, get_pupil='no', dnpup=50):
        """Add a Lyot stop, or an APP."""

        # load parameters
        npupil = 1  #conf['NPUPIL']
        pad = int((210 - npupil) / 2)

        # get LS misalignments
        LS_misalignment = (np.array([0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) *
                           npupil).astype(int)
        dx_amp, dy_amp, dz_amp = LS_misalignment[0:3]
        dx_phase, dy_phase, dz_phase = LS_misalignment[3:6]

        # case 1: Lyot stop (no APP)
        if APP is not True:

            # Lyot stop parameters: R_out, dR_in, spi_width
            # outer radius (absolute %), inner radius (relative %), spider width (m)
            (R_out, dR_in, spi_width) = [0.98, 0.03, 0]

            # Lyot stop inner radius at least as large as obstruction radius
            R_in = 0.15

            # case of a ring apodizer
            if RAVC is True:
                # define the apodizer transmission and apodizer radius [Mawet2013]
                # apodizer radius at least as large as obstruction radius
                T_ravc = 1 - (R_in**2 + R_in * np.sqrt(R_in**2 + 8)) / 4
                R_in /= np.sqrt(1 - T_ravc)

            # oversize Lyot stop inner radius
            R_in += dR_in

            # create Lyot stop
            proper.prop_circular_aperture(wf, R_out, dx_amp, dy_amp, NORM=True)
            if R_in > 0:
                proper.prop_circular_obscuration(wf,
                                                 R_in,
                                                 dx_amp,
                                                 dy_amp,
                                                 NORM=True)
            if spi_width > 0:
                for angle in [10]:
                    proper.prop_rectangular_obscuration(wf,
                                                        0.05 * 8,
                                                        8 * 1.3,
                                                        ROTATION=20)
                    proper.prop_rectangular_obscuration(wf,
                                                        8 * 1.3,
                                                        0.05 * 8,
                                                        ROTATION=20)
                    # proper.prop_rectangular_obscuration(wf, spi_width, 2 * 8, \
                    #                                     dx_amp, dy_amp, ROTATION=angle)

        # case 2: APP (no Lyot stop)
        else:
            # get amplitude and phase files
            APP_amp_file = os.path.join(conf['INPUT_DIR'],
                                        conf['APP_AMP_FILE'])
            APP_phase_file = os.path.join(conf['INPUT_DIR'],
                                          conf['APP_PHASE_FILE'])
            # get amplitude and phase data
            APP_amp = getdata(APP_amp_file) if os.path.isfile(APP_amp_file) \
                else np.ones((npupil, npupil))
            APP_phase = getdata(APP_phase_file) if os.path.isfile(APP_phase_file) \
                else np.zeros((npupil, npupil))
            # resize to npupil
            APP_amp = resize(APP_amp, (npupil, npupil),
                             preserve_range=True,
                             mode='reflect')
            APP_phase = resize(APP_phase, (npupil, npupil),
                               preserve_range=True,
                               mode='reflect')
            # pad with zeros to match PROPER gridsize
            APP_amp = np.pad(APP_amp, [(pad + 1 + dx_amp, pad - dx_amp), \
                                       (pad + 1 + dy_amp, pad - dy_amp)], mode='constant')
            APP_phase = np.pad(APP_phase, [(pad + 1 + dx_phase, pad - dx_phase), \
                                           (pad + 1 + dy_phase, pad - dy_phase)], mode='constant')
            # multiply the loaded APP
            proper.prop_multiply(wf, APP_amp * np.exp(1j * APP_phase))

        # get the pupil amplitude or phase for output
        if get_pupil.lower() in 'amplitude':
            return wf, proper.prop_get_amplitude(wf)[pad + 1 - dnpup:-pad +
                                                     dnpup, pad + 1 -
                                                     dnpup:-pad + dnpup]
        elif get_pupil.lower() in 'phase':
            return wf, proper.prop_get_phase(wf)[pad + 1 - dnpup:-pad + dnpup,
                                                 pad + 1 - dnpup:-pad + dnpup]
        else:
            return wf
예제 #13
0
def pupil(diam,
          gridsize,
          spiders_width,
          spiders_angle,
          pixelsize,
          r_obstr,
          wavelength,
          pupil_file,
          missing_segments_number=0,
          Debug='False',
          Debug_print='False',
          prefix='test'):

    beam_ratio = pixelsize * 4.85e-9 / (wavelength / diam)
    wfo = proper.prop_begin(diam, wavelength, gridsize, beam_ratio)
    n = int(gridsize)
    npupil = np.ceil(
        gridsize * beam_ratio
    )  # compute the pupil size --> has to be ODD (proper puts the center in the up right pixel next to the grid center)
    if npupil % 2 == 0:
        npupil = npupil + 1

    if (Debug_print == True):
        print("npupil: ", npupil)
        print("lambda: ", wavelength)

    if (missing_segments_number == 0):
        if (isinstance(pupil_file, (list, tuple, np.ndarray)) == True):
            pupil = pupil_file
            pupil_pixels = (pupil.shape)[0]  ## fits file size
            scaling_factor = float(npupil) / float(
                pupil_pixels
            )  ## scaling factor between the fits file size and the pupil size of the simulation
            if (Debug_print == True):
                print("scaling_factor: ", scaling_factor)
            pupil_scale = cv2.resize(
                pupil.astype(np.float32), (0, 0),
                fx=scaling_factor,
                fy=scaling_factor,
                interpolation=cv2.INTER_LINEAR
            )  # scale the pupil to the pupil size of the simualtions
            if (Debug_print == True):
                print("pupil_resample", pupil_scale.shape)
            pupil_large = np.zeros(
                (n, n))  # define an array of n-0s, where to insert the pupuil
            if (Debug_print == True):
                print("n: ", n)
                print("npupil: ", npupil)
            pupil_large[
                int(n / 2) + 1 - int(npupil / 2) - 1:int(n / 2) + 1 +
                int(npupil / 2),
                int(n / 2) + 1 - int(npupil / 2) - 1:int(n / 2) + 1 +
                int(npupil / 2
                    )] = pupil_scale  # insert the scaled pupil into the 0s grid

        proper.prop_circular_aperture(
            wfo, diam / 2)  # create a wavefront with a circular pupil

        if (isinstance(pupil_file, (list, tuple, np.ndarray)) == True):
            proper.prop_multiply(wfo, pupil_large)  # multiply the saved pupil
        else:
            proper.prop_circular_obscuration(
                wfo, r_obstr, NORM=True
            )  # create a wavefront with a circular central obscuration
        if (spiders_width != 0):
            for iter in range(0, len(spiders_angle)):
                proper.prop_rectangular_obscuration(
                    wfo, spiders_width, 2 * diam,
                    ROTATION=spiders_angle[iter])  # define the spiders
    else:
        if (missing_segments_number == 1):
            pupil = fits.getdata(
                input_dir +
                '/ELT_2048_37m_11m_5mas_nospiders_1missing_cut.fits')
        if (missing_segments_number == 2):
            pupil = fits.getdata(
                input_dir +
                '/ELT_2048_37m_11m_5mas_nospiders_2missing_cut.fits')
        if (missing_segments_number == 4):
            pupil = fits.getdata(
                input_dir +
                '/ELT_2048_37m_11m_5mas_nospiders_4missing_cut.fits')
        if (missing_segments_number == 7):
            pupil = fits.getdata(
                input_dir +
                '/ELT_2048_37m_11m_5mas_nospiders_7missing_1_cut.fits')

        pupil_pixels = (pupil.shape)[0]  ## fits file size
        scaling_factor = float(npupil) / float(
            pupil_pixels
        )  ## scaling factor between the fits file size and the pupil size of the simulation
        if (Debug_print == True):
            print("scaling_factor: ", scaling_factor)
        pupil_scale = cv2.resize(
            pupil.astype(np.float32), (0, 0),
            fx=scaling_factor,
            fy=scaling_factor,
            interpolation=cv2.INTER_LINEAR
        )  # scale the pupil to the pupil size of the simualtions
        if (Debug_print == True):
            print("pupil_resample", pupil_scale.shape)
        pupil_large = np.zeros(
            (n, n))  # define an array of n-0s, where to insert the pupuil
        if (Debug_print == True):
            print("n: ", n)
            print("npupil: ", npupil)
        pupil_large[
            int(n / 2) + 1 - int(npupil / 2) - 1:int(n / 2) + 1 +
            int(npupil / 2),
            int(n / 2) + 1 - int(npupil / 2) - 1:int(n / 2) + 1 +
            int(npupil /
                2)] = pupil_scale  # insert the scaled pupil into the 0s grid

        proper.prop_multiply(wfo, pupil_large)  # multiply the saved pupil
        if (spiders_width != 0):
            for iter in range(0, len(spiders_angle)):
                proper.prop_rectangular_obscuration(
                    wfo, spiders_width, 2 * diam,
                    ROTATION=spiders_angle[iter])  # define the spiders

    if (Debug == True):
        fits.writeto(
            out_dir + prefix + '_intial_pupil.fits',
            proper.prop_get_amplitude(wfo)[int(n / 2) -
                                           int(npupil / 2 + 50):int(n / 2) +
                                           int(npupil / 2 + 50),
                                           int(n / 2) -
                                           int(npupil / 2 + 50):int(n / 2) +
                                           int(npupil / 2 + 50)],
            overwrite=True)

    proper.prop_define_entrance(wfo)  #define the entrance wavefront
    wfo.wfarr *= 1. / np.amax(wfo._wfarr)  # max(amplitude)=1
    return (npupil, wfo)
예제 #14
0
def create_pupil(nhr=2**10,
                 npupil=285,
                 pupil_img_size=40,
                 diam_ext=37,
                 diam_int=11,
                 spi_width=0.5,
                 spi_angles=[0, 60, 120],
                 seg_width=0,
                 seg_gap=0,
                 seg_rms=0,
                 seg_ny=[
                     10, 13, 16, 19, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
                     30, 31, 30, 31, 30, 31, 30, 31, 30, 29, 28, 27, 26, 25,
                     24, 23, 22, 19, 16, 13, 10
                 ],
                 seg_missing=[],
                 seed=123456,
                 **conf):
    ''' Create a pupil.
    
    Args:
        nhr: int
            high resolution grid
        npupil: int
            number of pixels of the pupil
        pupil_img_size: float
            pupil image (for PROPER) in m
        diam_ext: float
            outer circular aperture in m
        diam_int: float
            central obscuration in m
        spi_width: float
            spider width in m
        spi_angles: list of float
            spider angles in deg
        seg_width: float
            segment width in m
        seg_gap: float
            gap between segments in m
        seg_rms: float
            rms of the reflectivity of all segments
        seg_ny: list of int
            number of hexagonal segments per column (from left to right)
        seg_missing: list of tupples
            coordinates of missing segments
    
    '''

    # create a high res pupil with PROPER of even size (nhr)
    nhr_size = pupil_img_size * nhr / (nhr - 1)
    wf_tmp = proper.prop_begin(nhr_size, 1, nhr, diam_ext / nhr_size)
    if diam_ext > 0:
        proper.prop_circular_aperture(wf_tmp, 1, NORM=True)
    if diam_int > 0:
        proper.prop_circular_obscuration(wf_tmp,
                                         diam_int / diam_ext,
                                         NORM=True)
    if spi_width > 0:
        for angle in spi_angles:
            proper.prop_rectangular_obscuration(wf_tmp, spi_width/nhr_size, 2, \
                ROTATION=angle, NORM=True)
    pup = proper.prop_get_amplitude(wf_tmp)
    # crop the pupil to odd size (nhr-1), and resize to npupil
    pup = pup[1:, 1:]
    pup = resize_img(pup, npupil)
    # add segments
    if seg_width > 0:
        segments = np.zeros((nhr, nhr))
        # sampling in meters/pixel
        sampling = pupil_img_size / nhr
        # dist between center of two segments, side by side
        seg_d = seg_width * np.cos(np.pi / 6) + seg_gap
        # segment radius
        seg_r = seg_width / 2
        # segment radial distance wrt x and y axis
        seg_ny = np.array(seg_ny)
        seg_nx = len(seg_ny)
        seg_rx = np.arange(seg_nx) - (seg_nx - 1) / 2
        seg_ry = (seg_ny - 1) / 2
        # loop through segments
        np.random.seed(seed)
        for i in range(seg_nx):
            seg_x = seg_rx[i] * seg_d * np.cos(np.pi / 6)
            seg_y = -seg_ry[i] * seg_d
            for j in range(1, seg_ny[i] + 1):
                # removes secondary and if any missing segment is present
                if (np.sqrt(seg_x**2 + seg_y**2) <= 4.01*seg_d) \
                        or ((seg_rx[i], j) in seg_missing):
                    seg_y += seg_d
                else:
                    # creates one hexagonal segment at x, y position in meters
                    segment = create_hexagon(nhr, seg_r, seg_y, seg_x,
                                             sampling)
                    # multiply by segment reflectivity and add to segments
                    seg_refl = np.random.normal(1, seg_rms)
                    segments += segment * seg_refl
                    seg_y += seg_d
        # need to transpose, due to the orientation of hexagons in create_hexagon
        segments = segments.T
        # resize to npupil, and add to pupil
        segments = resize_img(segments, npupil)
        pup *= segments

    return pup
예제 #15
0
def apodizer(wf,
             mode='RAVC',
             ravc_t=0.8,
             ravc_r=0.6,
             ravc_misalign=None,
             ngrid=1024,
             npupil=285,
             file_ravc_amp='',
             file_ravc_phase='',
             margin=50,
             get_amp=False,
             get_phase=False,
             verbose=False,
             **conf):
    ''' Create a wavefront object at the entrance pupil plane. 
    The pupil is either loaded from a fits file, or created using 
    pupil parameters.
    Can also select only one petal and mask the others.

    wf: WaveFront
        PROPER wavefront object
    mode: str
        HCI mode
    ravc_t: float
        RA transmittance
    ravc_r: float
        RA radius
    ravc_misalign: list of float
        RA misalignment
    ngrid: int
        number of pixels of the wavefront array
    npupil: int
        number of pixels of the pupil
    file_ravc_amp: str
    file_ravc_phase: str 
        ring apodizer files (optional)
    
    '''

    if mode in ['RAVC']:

        # load apodizer from files if provided
        if os.path.isfile(file_ravc_amp) and os.path.isfile(file_ravc_phase):
            if verbose is True:
                print('Load ring apodizer from files\n')
            # get amplitude and phase data
            RAVC_amp = fits.getdata(file_ravc_amp)
            RAVC_phase = fits.getdata(file_ravc_phase)
            # resize to npupil
            RAVC_amp = impro.resize_img(RAVC_amp, npupil)
            RAVC_phase = impro.resize_img(RAVC_phase, npupil)
            # pad with zeros to match PROPER gridsize
            RAVC_amp = impro.pad_img(RAVC_amp, ngrid)
            RAVC_phase = impro.pad_img(RAVC_phase, ngrid)
            # build complex apodizer
            apo = RAVC_amp * np.exp(1j * RAVC_phase)

        # or else, define the apodizer as a ring (with % misalignments)
        else:
            # RAVC misalignments
            ravc_misalign = [
                0, 0, 0, 0, 0, 0
            ] if ravc_misalign is None else list(ravc_misalign)
            dx_amp, dy_amp, dz_amp = ravc_misalign[0:3]
            dx_phase, dy_phase, dz_phase = ravc_misalign[3:6]
            # create apodizer
            apo = circular_apodization(wf, ravc_r, 1., ravc_t, xc=dx_amp, \
                yc=dy_amp, NORM=True)
            apo = proper.prop_shift_center(apo)
            if verbose is True:
                print('Create ring apodizer')
                print('   ravc_t=%3.4f, ravc_r=%3.4f'\
                    %(ravc_t, ravc_r))
                print('   ravc_misalign=%s' % ravc_misalign)
                print('')

        # multiply the loaded apodizer
        proper.prop_multiply(wf, apo)

        # get the apodizer amplitude and phase for output
        apo_amp = impro.crop_img(proper.prop_get_amplitude(wf), npupil,\
                margin) if get_amp is True else None
        apo_phase = impro.crop_img(proper.prop_get_phase(wf), npupil,\
                margin) if get_phase is True else None

        return wf, apo_amp, apo_phase

    else:  # no ring apodizer
        return wf, None, None
예제 #16
0
def speck_killing_loop(wfo):
    #configfilename = 'speckle_null_config.ini'
    #config = ConfigObj(configfilename)
    configfilename = tp.FPWFSdir + 'speckle_null_config_Rupe.ini'
    hardwareconfigfile = tp.FPWFSdir + 'speckle_instruments.ini'
    configspecfile = tp.FPWFSdir + 'speckle_null_config.spec'
    print(configfilename)
    config = ConfigObj(configfilename, configspec=configspecfile)
    val = Validator()
    check = config.validate(val)

    #pharo = hardware.PHARO_COM('PHARO',
    #            configfile = hardwareconfigfile)
    #p3k = hardware.P3K_COM('P3K_COM', configfile = hardwareconfigfile)
    camera = hardware.camera()
    ao = hardware.ao()
    apmask = False
    if not apmask:
        aperturemask = np.ones((66, 66))
    if apmask:
        aperturemask = dm.annularmask(66, 12, 33)

    # nulled_field = None
    im_params = config['IM_PARAMS']
    null_params = config['NULLING']
    abc = config['INTENSITY_CAL']['abc']

    use_centoffs = config['NULLING']['cent_off']

    #bgds = flh.setup_bgd_dict(config)
    fake_bgds = {
        'bkgd': np.zeros((tp.grid_size, tp.grid_size)),
        'masterflat': np.ones((tp.grid_size, tp.grid_size)),
        'badpix': np.zeros((tp.grid_size, tp.grid_size))
    }
    print("WARNING: USING FAKE BGDS")
    bgds = fake_bgds.copy()
    # controlregion = pf.open(tp.FPWFSdir+config['CONTROLREGION']['filename'])[0].data
    # controlregion = controlregion[512-int(tp.grid_size/2):512+int(tp.grid_size/2), 512-int(tp.grid_size/2):512+int(tp.grid_size/2)]
    # controlregion = np.roll(controlregion, 15)
    # controlregion[:,0:70] = 0
    # controlregion[:80] = 0
    # controlregion[-80:] = 0
    controlregion = np.zeros((tp.grid_size, tp.grid_size))
    controlregion[50:80, 35:50] = 1
    boarder = get_ctrlrgnBoarder(controlregion)

    quicklook_im(controlregion, logAmp=False)
    # plt.show(block=True)

    #Notes==>scale exptime in snr
    exp = config['INTENSITY_CAL']['exptime']
    #Setup
    # initial_flatmap = ao.grab_current_flatmap()
    # initial_centoffs= ao.grab_current_centoffs()

    defaultim = np.ones((tp.grid_size, tp.grid_size))

    vertsx = config['CONTROLREGION']['verticesx']
    vertsy = config['CONTROLREGION']['verticesy']

    # plt.ion()
    fig = plt.figure(figsize=(12, 12))
    ax1 = plt.subplot2grid((4, 4), (0, 0), rowspan=2, colspan=2)
    ax2 = plt.subplot2grid((4, 4), (0, 2), rowspan=2, colspan=2)
    ax3 = plt.subplot2grid((4, 4), (3, 0))
    ax4 = plt.subplot2grid((4, 4), (2, 2), rowspan=2, colspan=2)
    #ax5 = plt.subplot2grid((4,4),(3,2))
    # ax1b =plt.subplot2grid((4,4),(0, 0), rowspan =2, colspan = 2)

    title = fig.suptitle('Speckle destruction')
    ax1.set_title('Image')
    ax2.set_title('Control region')
    ax3.set_title('RMS in region')
    ax4.set_title('Image')
    #ax5.set_title('Intensity')

    w1 = ax1.imshow(np.log10(np.abs(defaultim)) + boarder,
                    origin='lower',
                    interpolation='nearest')
    current_cmap = cm.get_cmap()
    current_cmap.set_bad(color='white')
    # w1b = ax1b.imshow(boarder*10, origin='lower', interpolation = 'none')
    # ax1.set_xlim(min(vertsx), max(vertsx))
    # ax1.set_ylim(min(vertsy), max(vertsy))
    #ax1.set_ylim(int(im_params['centery'])-25, int(im_params['centery']+50))

    w2 = ax2.imshow(np.log(np.abs(controlregion * defaultim)),
                    origin='lower',
                    interpolation='nearest')
    # ax2.set_xlim(min(vertsx), max(vertsx))
    # ax2.set_ylim(min(vertsy), max(vertsy))

    w3 = ax3.plot([], [])
    ax3.set_xlim(0, 10)

    w4, = ax4.plot(np.abs(defaultim[64]))
    # w4 = ax4.imshow(np.log10(np.abs(defaultim))+boarder, origin='lower', interpolation = 'nearest')
    current_cmap = cm.get_cmap()
    current_cmap.set_bad(color='white')

    N_iterations = 10
    itcounter = []
    maxfluxes = []
    meanfluxes = []
    totalfluxes = []
    rmsfluxes = []
    #w5 = ax5.plot(np.arange(10)*0, np.arange(10)*0)
    # w4 = ax4.imshow(np.log(camera.take_src_return_imagedata(exptime =exp)[242:758, 242:758]), origin='lower', interpolation = 'nearest')

    plt.show()
    tstamp = time.strftime("%Y%m%d-%H%M%S").replace(' ', '_')

    cubeoutputdir = os.path.join(null_params['outputdir'], tstamp)
    if not os.path.exists(cubeoutputdir):
        os.makedirs(cubeoutputdir)

    print(configfilename)
    result_imagecube = output_imagecube(N_iterations,
                                        tp.grid_size,
                                        filepath=os.path.join(
                                            cubeoutputdir,
                                            'test_' + tstamp + '.fits'),
                                        comment='fun',
                                        configfile=configfilename)

    clean_imagecube = output_imagecube(N_iterations,
                                       tp.grid_size,
                                       filepath=os.path.join(
                                           cubeoutputdir,
                                           'test_clean_' + tstamp + '.fits'),
                                       comment='fun',
                                       configfile=configfilename)

    cal_imagecube = output_imagecube(4,
                                     tp.grid_size,
                                     filepath=os.path.join(
                                         cubeoutputdir,
                                         'test_cals_' + tstamp + '.fits'),
                                     comment='fun',
                                     configfile=configfilename)
    cal_imagecube.update(controlregion)
    cal_imagecube.update(bgds['bkgd'])
    cal_imagecube.update(bgds['masterflat'])
    cal_imagecube.update(bgds['badpix'])

    ####MAIN LOOP STARTS HERE#####
    print("BEGINNING NULLING LOOP")

    for iteration in range(N_iterations):
        # quicklook_wf(wfo)
        itcounter.append(iteration)

        if use_centoffs == False:
            current_flatmap = ao.grab_current_flatmap()
        if use_centoffs == True:
            current_centoffs = ao.grab_current_centoffs()
        # quicklook_im(current_flatmap, logAmp=False, show=True)
        print("Taking image of speckle field")
        # if nulled_field != None:
        #     raw_im = nulled_field
        # else:
        raw_im = camera.take_src_return_imagedata(wfo, exptime=exp)

        result_imagecube.update(raw_im)
        field_im = pre.equalize_image(raw_im, **bgds)
        clean_imagecube.update(field_im)

        field_ctrl = field_im * controlregion
        # print np.shape(field_im), np.shape(controlregion), np.shape(field_ctrl)
        # plt.figure()
        # plt.imshow(field_im)
        # plt.figure()
        # plt.imshow(controlregion)
        # plt.figure()
        # plt.imshow(field_ctrl)
        # plt.show(block=True)

        meanfluxes.append(np.mean(field_ctrl[field_ctrl > 0]))
        maxfluxes.append(np.max(field_ctrl[field_ctrl > 0]))
        totalfluxes.append(np.sum(field_ctrl))
        rmsfluxes.append(
            np.std(field_ctrl[field_ctrl > 0]) /
            config['NULLING']['referenceval'])

        ax3.plot(itcounter, rmsfluxes)
        #w5 = plt.plot(itcounter, maxfluxes)
        #w5 = plt.plot(itcounter, totalfluxes)
        ax1.set_title('Iteration: ' + str(iteration) + ',  Mean: ' +
                      str(meanfluxes[iteration]) + ',  Max: ' +
                      str(maxfluxes[iteration]))
        w1.set_data(np.log(np.abs(field_ctrl)) + boarder)

        w1.autoscale()
        plt.draw()
        plt.pause(0.02)

        if iteration > 0:
            try:
                printstats(field_im, speckleslist)
            except:
                pass
            flh.writeout(current_flatmap, 'latestiteration.fits')

        # ans = raw_input('Do you want to run a speckle nulling iteration[Y/N]?')
        ans = 'Y'
        if ans == 'N':
            flatmapans = eval(
                input('Do you want to reload the' +
                      'flatmap/centoffs you started with[Y/N]?'))
            if flatmapans == 'Y':
                print("Reloading initial flatmap/centoffs")

                if use_centoffs == False:
                    status = ao.load_new_flatmap((initial_flatmap))
                if use_centoffs == True:
                    status = ao.load_new_centoffs((initial_centoffs))
                #ao.load_new_flatmap(initial_flatmap)
            break

        print(('Iteration ' + str(iteration) + ' total_intensity: ' +
               str(np.sum(field_ctrl))))
        #return a list of points
        print("computing interesting bright spots")

        #note indices and coordinates are reversed
        ijofinterest = identify_bright_points(field_ctrl, controlregion)
        xyofinterest = [p[::-1] for p in ijofinterest]

        print(("computed ", str(len(xyofinterest)), " bright spots"))
        max_specks = config['DETECTION']['max_speckles']

        #if len(xyofinterest)>50:
        #    xyofinterest = xyofinterest[0:49]

        if len(xyofinterest) < max_specks:
            max_specks = len(xyofinterest)

        fps = filterpoints(xyofinterest,
                           max=max_specks,
                           rad=config['NULLING']['exclusionzone'])
        print(fps)
        print("creating speckle objects")
        speckleslist = [speckle(field_im, xy[0], xy[1], config) for xy in fps]
        speckleslist = [x for x in speckleslist if (x.intensity) > 0]
        #old way--filter the speckles
        #speckleslist =[speckle(field_im, xy[0], xy[1], config) for xy in xyofinterest]
        #speckleslist = filterspeckles(speckleslist, max = max_specks)
        phases = null_params['phases']
        # phases = [-np.pi/2.,0,np.pi/2.,np.pi]
        for idx, phase in enumerate(phases):
            print(("Phase ", phase))
            phaseflat = 0
            allspeck_aps = 0
            #put in sine waves at speckle locations
            for speck in speckleslist:
                #XXX
                # phaseflat= phaseflat+speck.generate_flatmap(phase)
                phaseflat = speck.generate_flatmap(phase)
                # quicklook_im(speck.generate_flatmap(phase), logAmp=False)
                allspeck_aps = allspeck_aps + speck.aperture
            print('here')
            ax2.set_title('Phase: ' + str(phase))
            if idx == 0:
                # w1.set_data( (allspeck_aps*field_ctrl)-0.95*field_ctrl)
                w1.set_data(
                    np.log(np.abs((allspeck_aps * field_im) -
                                  0.95 * field_im)) + boarder)
                w1.autoscale()
                plt.draw()
            #w1.set_data(field_ctrl); w1.autoscale(); plt.draw()

            phaseflat = phaseflat * aperturemask
            # plt.figure()
            # plt.imshow(allspeck_aps)
            # plt.show()
            # ans = raw_input('press enter')
            wf_temp = copy.copy(wfo)
            if use_centoffs == False:
                status = ao.load_new_flatmap(current_flatmap + phaseflat,
                                             wf_temp)
            # if use_centoffs == True:
            #     status = ao.load_new_centoffs(current_centoffs+
            #                  fmf.convert_flatmap_centoffs(phaseflat))
            tp.variable = proper.prop_get_phase(wf_temp)[20, 20]
            print(('speck phase', tp.variable, 'intensity',
                   proper.prop_get_amplitude(wf_temp)[20, 20]))
            # plt.show(block=True)
            # quicklook_wf(wf_temp, show=True)

            phaseim = camera.take_src_return_imagedata(wf_temp, exptime=exp)
            # quicklook_im(phaseim, show=True)
            phaseim = pre.equalize_image(phaseim, **bgds)
            # quicklook_im(phaseim, show=True)
            w2.set_data(np.log(np.abs(phaseim * controlregion)))
            w2.autoscale()
            plt.draw()
            plt.pause(0.02)

            # w4.set_data(range(128), np.sum(np.eye(tp.grid_size)*proper.prop_get_amplitude(wf_temp),axis=1))#ax4.plot(range(128),  proper.prop_get_amplitude(wf_temp)[20])#np.abs(field_im[20]))#+boarder)
            w4.set_data(
                list(range(128)),
                proper.prop_get_amplitude(wf_temp)[64]
            )  # ax4.plot(range(128),  proper.prop_get_amplitude(wf_temp)[20])#np.abs(field_im[20]))#+boarder)
            ax4.set_xlim([0, 128])
            ax4.set_ylim([0, 0.2])

            print("recomputing intensities")
            for speck in speckleslist:
                phase_int = speck.recompute_intensity(phaseim)
                speck.phase_intensities[idx] = phase_int

            print((speck.phase_intensities))
            time.sleep(3)
        # if use_centoffs == False:
        #     ao.load_new_flatmap(current_flatmap, wf_temp)
        # # if use_centoffs == True:
        # #     ao.load_new_centoffs(current_centoffs)

        if config['NULLING']['null_gain'] == False:
            defaultgain = config['NULLING']['default_flatmap_gain']

            nullmap = generate_phase_nullmap(speckleslist, defaultgain, phases)
            nullmap = nullmap * aperturemask
            if use_centoffs == False:
                # ao.load_new_flatmap(current_flatmap + nullmap, wfo)
                ao.load_new_flatmap(nullmap, wfo)
            # FPWFS.quicklook_wf(wfo)
            # camera.take_src_return_imagedata(wfo, exptime=exp)
            # if use_centoffs == True:
            #     ao.load_new_centoffs(current_centoffs+ fmf.convert_flatmap_centoffs(nullmap))

        # ans = raw_input('press enter')
        if config['NULLING']['null_gain'] == True:
            ##NOW CALCULATE GAIN NULLS

            print("DETERMINING NULL GAINS")
            gains = config['NULLING']['amplitudegains']
            for idx, gain in enumerate(gains):
                print("Checking optimal gains")
                nullmap = generate_phase_nullmap(speckleslist, gain, phases)
                nullmap = nullmap * aperturemask

                wf_temp = copy.copy(wfo)
                if use_centoffs == False:
                    ao.load_new_flatmap(current_flatmap + nullmap, wf_temp)
                # if use_centoffs == True:
                #     ao.load_new_centoffs(current_centoffs+ fmf.convert_flatmap_centoffs(nullmap))

                ampim = camera.take_src_return_imagedata(wf_temp, exptime=exp)
                # quicklook_wf(wf_temp)
                ampim = pre.equalize_image(ampim, **bgds)
                w2.set_data(np.log(np.abs(ampim * controlregion)))
                ax2.set_title('Gain: ' + str(gain))
                w2.autoscale()
                plt.draw()
                plt.pause(0.02)
                for speck in speckleslist:
                    amp_int = speck.recompute_intensity(ampim)
                    speck.gain_intensities[idx] = amp_int
                print((speck.gain_intensities))
                w4.set_data(
                    list(range(128)),
                    proper.prop_get_amplitude(wf_temp)[64]
                )  #ax4.plot(range(128),  proper.prop_get_amplitude(wf_temp)[20])#np.abs(field_im[20]))#+boarder)
                ax4.set_xlim([0, 128])
                ax4.set_ylim([0, 0.2])
            for speck in speckleslist:
                speck.compute_null_gain()
            supernullmap = generate_super_nullmap(speckleslist, phases)
            print(
                "Loading supernullmap now that optimal gains have been found!")
            supernullmap = supernullmap * aperturemask
            if use_centoffs == False:
                # ao.load_new_flatmap(current_flatmap + supernullmap, wfo)
                ao.load_new_flatmap(supernullmap, wfo)
            # FPWFS.quicklook_wf(wfo)
            # quicklook_im(supernullmap,logAmp=False, show=True)

            # camera.take_src_return_imagedata(wfo, exptime=exp)
            # if use_centoffs == True:
            #     ao.load_new_centoffs(current_centoffs+ fmf.convert_flatmap_centoffs(supernullmap))
            #ao.load_new_flatmap(supernullmap)
            # w3.set_data(nullmap)

            # plt.draw()
        # w4.set_data(np.log(np.abs(field_im))+boarder)
        # plt.draw()
        # w4.autoscale();
        # quicklook_im(field_im, logAmp=False)
        quicklook_wf(wfo)
        plt.show(block=True)

        # ans = raw_input('press enter')
        # try:
        #     check = raw_input("would you like to continue?: ")
        # except EOFError:
        #     print ("Error: EOF or empty input!")
        #     check = ""
        # print check
        plt.show(block=False)
예제 #17
0
def simple_telescope(wavelength, gridsize):

    # Define entrance aperture diameter and other quantities
    d_objective = 5.0  # objective diameter in meters
    fl_objective = 20.0 * d_objective  # objective focal length in meters
    fl_eyepiece = 0.021  # eyepiece focal length
    fl_eye = 0.022  # human eye focal length
    beam_ratio = 0.3  # initial beam width/grid width

    # Define the wavefront
    wfo = proper.prop_begin(d_objective, wavelength, gridsize, beam_ratio)

    # print d_objective, wavelength, gridsize, beam_ratio
    # Define a circular aperture
    proper.prop_circular_aperture(wfo, d_objective / 2)

    # proper.prop_propagate(wfo, fl_objective)
    # proper.prop_propagate(wfo, fl_objective)
    # proper.prop_propagate(wfo, fl_objective)

    # plt.imshow(proper.prop_get_amplitude(wfo))
    # plt.show()

    # Define entrance
    proper.prop_define_entrance(wfo)
    # plt.imshow(proper.prop_get_amplitude(wfo))
    # plt.show()

    # proper.prop_propagate(wfo, fl_objective+fl_eyepiece, "eyepiece")
    # # plt.imshow(proper.prop_get_amplitude(wfo))
    # # plt.show()
    #
    # proper.prop_propagate(wfo, fl_objective+fl_eyepiece, "eyepiece")
    # plt.imshow(proper.prop_get_amplitude(wfo))
    # plt.show()
    #
    # proper.prop_propagate(wfo, fl_objective+fl_eyepiece, "eyepiece")
    # plt.imshow(proper.prop_get_amplitude(wfo))
    # plt.show()

    # Define a lens
    proper.prop_lens(wfo, fl_objective, "objective")
    # plt.imshow(proper.prop_get_amplitude(wfo))
    # plt.show()
    # Propagate the wavefront
    proper.prop_propagate(wfo, fl_objective + fl_eyepiece, "eyepiece")
    # plt.imshow(proper.prop_get_amplitude(wfo))
    # plt.show()
    # Define another lens
    proper.prop_lens(wfo, fl_eyepiece, "eyepiece")
    # plt.imshow(proper.prop_get_amplitude(wfo))
    # plt.show()
    exit_pupil_distance = fl_eyepiece / (1 - fl_eyepiece /
                                         (fl_objective + fl_eyepiece))
    proper.prop_propagate(wfo, exit_pupil_distance, "exit pupil at eye lens")
    # quicklook_wf(wfo)
    # plt.imshow(proper.prop_get_amplitude(wfo))
    # plt.show()
    proper.prop_lens(wfo, fl_eye, "eye")
    proper.prop_propagate(wfo, fl_eye, "retina")
    # plt.imshow(proper.prop_get_amplitude(wfo))
    # plt.show()
    quicklook_wf(wfo)
    phase_map = proper.prop_get_phase(wfo)
    amp_map = proper.prop_get_amplitude(wfo)
    # quicklook_im(phase_map)

    amp_map[80:100, 80:100] = 0
    quicklook_im(amp_map, logAmp=True)

    import numpy as np
    wfo.wfarr = proper.prop_shift_center(amp_map * np.cos(phase_map) +
                                         1j * amp_map * np.sin(phase_map))
    # quicklook_wf(wf_array[iw,0])
    proper.prop_propagate(wfo, fl_eye, "retina")
    proper.prop_lens(wfo, fl_eye, "eye")
    quicklook_wf(wfo)

    # End
    (wfo, sampling) = proper.prop_end(wfo)

    return (wfo, sampling)
예제 #18
0
def lyotstop(wf, conf, RAVC):
    input_dir = conf['INPUT_DIR']
    diam = conf['DIAM']
    npupil = conf['NPUPIL']
    spiders_angle = conf['SPIDERS_ANGLE']
    r_obstr = conf['R_OBSTR']
    Debug = conf['DEBUG']
    Debug_print = conf['DEBUG_PRINT']
    LS_amplitude_apodizer_file = conf['AMP_APODIZER']
    LS_misalignment = np.array(conf['LS_MIS_ALIGN'])
    if conf['PHASE_APODIZER_FILE'] == 0:
        LS_phase_apodizer_file = 0
    else:
        LS_phase_apodizer_file = fits.getdata(input_dir + '/' +
                                              conf['PHASE_APODIZER_FILE'])
    LS = conf['LYOT_STOP']
    LS_parameters = np.array(conf['LS_PARA'])
    n = proper.prop_get_gridsize(wf)
    if (RAVC == True):  # define the inner radius of the Lyot Stop
        t1_opt = 1. - 1. / 4 * (
            r_obstr**2 + r_obstr * (math.sqrt(r_obstr**2 + 8.))
        )  # define the apodizer transmission [Mawet2013]
        R1_opt = (r_obstr / math.sqrt(1. - t1_opt)
                  )  # define teh apodizer radius [Mawet2013]
        r_LS = R1_opt + LS_parameters[
            1]  # when a Ring apodizer is present, the inner LS has to have at least the value of the apodizer radius
    else:
        r_LS = r_obstr + LS_parameters[
            1]  # when no apodizer, the LS has to have at least the radius of the pupil central obstruction
    if LS == True:  # apply the LS
        if (Debug_print == True):
            print("LS parameters: ", LS_parameters)
        proper.prop_circular_aperture(wf,
                                      LS_parameters[0],
                                      LS_misalignment[0],
                                      LS_misalignment[1],
                                      NORM=True)
        proper.prop_circular_obscuration(wf,
                                         r_LS,
                                         LS_misalignment[0],
                                         LS_misalignment[1],
                                         NORM=True)
        if (LS_parameters[2] != 0):
            for iter in range(0, len(spiders_angle)):
                if (Debug_print == True):
                    print("LS_misalignment: ", LS_misalignment)
                proper.prop_rectangular_obscuration(
                    wf,
                    LS_parameters[2],
                    2 * diam,
                    LS_misalignment[0],
                    LS_misalignment[1],
                    ROTATION=spiders_angle[iter])  # define the spiders
        if (Debug == True):
            out_dir = str('./output_files/')
            fits.writeto(
                out_dir + '_Lyot_stop.fits',
                proper.prop_get_amplitude(wf)[int(n / 2) -
                                              int(npupil / 2 + 50):int(n / 2) +
                                              int(npupil / 2 + 50),
                                              int(n / 2) -
                                              int(npupil / 2 + 50):int(n / 2) +
                                              int(npupil / 2 + 50)],
                overwrite=True)

    if (isinstance(LS_phase_apodizer_file, (list, tuple, np.ndarray)) == True):
        xc_pixels = int(LS_misalignment[3] * npupil)
        yc_pixels = int(LS_misalignment[4] * npupil)
        apodizer_pixels = (LS_phase_apodizer_file.shape)[0]  ## fits file size
        scaling_factor = float(npupil) / float(
            apodizer_pixels
        )  ## scaling factor between the fits file size and the pupil size of the simulation

        #        scaling_factor = float(npupil)/float(pupil_pixels) ## scaling factor between the fits file size and the pupil size of the simulation
        if (Debug_print == True):
            print("scaling_factor: ", scaling_factor)
        apodizer_scale = cv2.resize(
            LS_phase_apodizer_file.astype(np.float32), (0, 0),
            fx=scaling_factor,
            fy=scaling_factor,
            interpolation=cv2.INTER_LINEAR
        )  # scale the pupil to the pupil size of the simualtions
        if (Debug_print == True):
            print("apodizer_resample", apodizer_scale.shape)
        apodizer_large = np.zeros(
            (n, n))  # define an array of n-0s, where to insert the pupuil
        if (Debug_print == True):
            print("npupil: ", npupil)
        apodizer_large[
            int(n / 2) + 1 - int(npupil / 2) - 1 + xc_pixels:int(n / 2) + 1 +
            int(npupil / 2) + xc_pixels,
            int(n / 2) + 1 - int(npupil / 2) - 1 + yc_pixels:int(n / 2) + 1 +
            int(npupil / 2) +
            yc_pixels] = apodizer_scale  # insert the scaled pupil into the 0s grid
        phase_multiply = np.array(np.zeros((n, n)),
                                  dtype=complex)  # create a complex array
        phase_multiply.imag = apodizer_large  # define the imaginary part of the complex array as the atm screen
        apodizer = np.exp(phase_multiply)
        proper.prop_multiply(wf, apodizer)
        if (Debug == True):
            fits.writeto('LS_apodizer.fits',
                         proper.prop_get_phase(wf),
                         overwrite=True)

    if (isinstance(LS_amplitude_apodizer_file,
                   (list, tuple, np.ndarray)) == True):
        print('4th')
        xc_pixels = int(LS_misalignment[0] * npupil)
        yc_pixels = int(LS_misalignment[1] * npupil)
        apodizer_pixels = (
            LS_amplitude_apodizer_file.shape)[0]  ## fits file size
        scaling_factor = float(npupil) / float(
            pupil_pixels
        )  ## scaling factor between the fits file size and the pupil size of the simulation
        if (Debug_print == True):
            print("scaling_factor: ", scaling_factor)
            apodizer_scale = cv2.resize(
                amplitude_apodizer_file.astype(np.float32), (0, 0),
                fx=scaling_factor,
                fy=scaling_factor,
                interpolation=cv2.INTER_LINEAR
            )  # scale the pupil to the pupil size of the simualtions
        if (Debug_print == True):
            print("apodizer_resample", apodizer_scale.shape)
        apodizer_large = np.zeros(
            (n, n))  # define an array of n-0s, where to insert the pupuil
        if (Debug_print == True):
            print("grid_size: ", n)
            print("npupil: ", npupil)
        apodizer_large[
            int(n / 2) + 1 - int(npupil / 2) - 1 + xc_pixels:int(n / 2) + 1 +
            int(npupil / 2) + xc_pixels,
            int(n / 2) + 1 - int(npupil / 2) - 1 + yc_pixels:int(n / 2) + 1 +
            int(npupil / 2) +
            yc_pixels] = apodizer_scale  # insert the scaled pupil into the 0s grid
        apodizer = apodizer_large
        proper.prop_multiply(wf, apodizer)
        if (Debug == True):
            fits.writeto('LS_apodizer.fits',
                         proper.prop_get_amplitude(wf),
                         overwrite=True)

    return wf
예제 #19
0
def scexao_model(lmda, grid_size, kwargs):
    """
    propagates instantaneous complex E-field thru Subaru from the DM through SCExAO

    uses PyPROPER3 to generate the complex E-field at the pupil plane, then propagates it through SCExAO 50x50 DM,
        then coronagraph, to the focal plane
    :returns spectral cube at instantaneous time in the focal_plane()
    """
    # print("Propagating Broadband Wavefront Through Subaru")

    # Initialize the Wavefront in Proper
    wfo = proper.prop_begin(entrance_d, lmda, grid_size, beam_ratio)

    # Defines aperture (baffle-before primary)
    proper.prop_circular_aperture(wfo, entrance_d / 2)
    proper.prop_define_entrance(wfo)  # normalizes abs intensity

    # Test Sampling
    if kwargs['verbose'] and kwargs['ix'] == 0:
        check1 = proper.prop_get_sampling(wfo)
        print(
            f"\n\tDM Pupil Plane\n"
            f"sampling at aperture is {check1 * 1e3:.4f} mm\n"
            f"Total Sim is {check1 * 1e3 * grid_size:.2f}x{check1 * 1e3 * grid_size:.2f} mm\n"
            f"Diameter of beam is {check1 * 1e3 * grid_size * beam_ratio:.4f} mm over {grid_size * beam_ratio} pix"
        )

    # SCExAO Reimaging 1
    proper.prop_lens(
        wfo, fl_SxOAPG)  # produces f#14 beam (approx exit beam of AO188)
    proper.prop_propagate(wfo, fl_SxOAPG * 2)  # move to second pupil
    if kwargs['verbose'] and kwargs['ix'] == 0:
        print(f"initial f# is {proper.prop_get_fratio(wfo):.2f}\n")

    ########################################
    # Import/Apply Actual DM Map
    # #######################################
    plot_flag = False
    if kwargs['verbose'] and kwargs['ix'] == 0:
        plot_flag = True

    dm_map = kwargs['map']
    errormap(wfo,
             dm_map,
             SAMPLING=dm_pitch,
             MIRROR_SURFACE=True,
             MASKING=True,
             BR=beam_ratio,
             PLOT=plot_flag)  # MICRONS=True

    if kwargs['verbose'] and kwargs['ix'] == 0:
        fig, subplot = plt.subplots(nrows=1, ncols=2, figsize=(12, 5))
        ax1, ax2 = subplot.flatten()
        fig.suptitle('SCExAO Model WFO after errormap',
                     fontweight='bold',
                     fontsize=14)
        ax1.imshow(proper.prop_get_amplitude(wfo), interpolation='none'
                   )  # np.abs(proper.prop_shift_center(wfo.wfarr))**2
        ax1.set_title('Amplitude')
        ax2.imshow(
            proper.prop_get_phase(wfo),
            interpolation=
            'none',  # np.angle(proper.prop_shift_center(wfo.wfarr))
            vmin=-1 * np.pi,
            vmax=1 * np.pi,
            cmap='hsv')  # , cmap='hsv'
        ax2.set_title('Phase')

    # ------------------------------------------------
    # SCExAO Reimaging 2
    proper.prop_lens(wfo, fl_SxOAPG)
    proper.prop_propagate(wfo,
                          fl_SxOAPG)  # focus at exit of DM telescope system
    proper.prop_lens(wfo, fl_SxOAPG)
    proper.prop_propagate(wfo,
                          fl_SxOAPG)  # focus at exit of DM telescope system

    # # Coronagraph
    SubaruPupil(wfo)  # focal plane mask
    # if kwargs['verbose'] and kwargs['ix']==0:
    #     fig, subplot = plt.subplots(nrows=1, ncols=2, figsize=(12, 5))
    #     ax1, ax2 = subplot.flatten()
    #     fig.suptitle('SCExAO Model WFO after FPM', fontweight='bold', fontsize=14)
    #     # ax.imshow(dm_map, interpolation='none')
    #     ax1.imshow(np.abs(proper.prop_shift_center(wfo.wfarr))**2, interpolation='none', norm=LogNorm(vmin=1e-7,vmax=1e-2))
    #     ax1.set_title('Amplitude')
    #     ax2.imshow(np.angle(proper.prop_shift_center(wfo.wfarr)), interpolation='none',
    #                vmin=-2*np.pi, vmax=2*np.pi, cmap='hsv')  # , cmap='hsv'
    #     ax2.set_title('Phase')
    proper.prop_propagate(wfo, fl_SxOAPG)
    proper.prop_lens(wfo, fl_SxOAPG)
    proper.prop_propagate(wfo, fl_SxOAPG)  # middle of 2f system
    proper.prop_circular_aperture(wfo, lyot_size, NORM=True)  # lyot stop
    proper.prop_propagate(wfo, fl_SxOAPG)  #
    proper.prop_lens(wfo, fl_SxOAPG)  # exit lens of gaussian telescope
    proper.prop_propagate(wfo, fl_SxOAPG)  # to focus

    # MEC Pickoff reimager.
    proper.prop_propagate(wfo, mec_parax_fl)  # to another pupil
    proper.prop_lens(
        wfo, mec_parax_fl)  # collimating lens, pupil size should be 8 mm
    proper.prop_propagate(wfo, mec1_fl +
                          .0142557)  # mec1_fl  .054  mec1_fl+.0101057
    # if kwargs['verbose'] and kwargs['ix']==0:
    #     current = proper.prop_get_beamradius(wfo)
    #     print(f'Beam Radius after SCExAO exit (at MEC foreoptics entrance) is {current*1e3:.3f} mm\n'
    #           f'current f# is {proper.prop_get_fratio(wfo):.2f}\n')

    # ##################################
    # MEC Optics Box
    # ###################################
    proper.prop_circular_aperture(wfo,
                                  0.00866)  # reading off the zemax diameter
    proper.prop_lens(wfo, mec1_fl)  # MEC lens 1
    proper.prop_propagate(wfo,
                          mec_l1_l2)  # there is a image plane at z=mec1_fl
    proper.prop_lens(wfo, mec2_fl)  # MEC lens 2 (tiny lens)
    proper.prop_propagate(wfo, mec_l2_l3)
    proper.prop_lens(wfo, mec3_fl)  # MEC lens 3
    proper.prop_propagate(wfo, mec3_fl,
                          TO_PLANE=False)  # , TO_PLANE=True mec_l3_focus

    # #######################################
    # Focal Plane
    # #######################################
    # Check Sampling in focal plane
    # shifts wfo from Fourier Space (origin==lower left corner) to object space (origin==center)
    # wf, samp = proper.prop_end(wfo, NoAbs=True)
    wf = proper.prop_shift_center(wfo.wfarr)
    wf = extract_center(wf, new_size=np.array(kwargs['psf_size']))
    samp = proper.prop_get_sampling(wfo)
    smp_asec = proper.prop_get_sampling_arcsec(wfo)

    if kwargs['verbose'] and kwargs['ix'] == 0:
        fig, subplot = plt.subplots(nrows=1, ncols=2, figsize=(12, 5))
        fig.subplots_adjust(left=0.08, hspace=.4, wspace=0.2)

        ax1, ax2 = subplot.flatten()
        fig.suptitle('SCExAO Model Focal Plane',
                     fontweight='bold',
                     fontsize=14)
        tic_spacing, tic_labels, axlabel = scale_lD(
            wfo, newsize=kwargs['psf_size'][0])
        tic_spacing[0] = tic_spacing[0] + 1  # hack for edge effects
        tic_spacing[-1] = tic_spacing[-1] - 1  # hack for edge effects

        im = ax1.imshow(
            np.abs(wf)**2,
            interpolation='none',
            norm=LogNorm(
                vmin=1e-7,
                vmax=1e-2))  # np.abs(proper.prop_shift_center(wfo.wfarr))**2
        ax1.set_xticks(tic_spacing)
        ax1.set_xticklabels(tic_labels)
        ax1.set_yticks(tic_spacing)
        ax1.set_yticklabels(tic_labels)
        ax1.set_ylabel(axlabel, fontsize=8)
        add_colorbar(im)

        im = ax2.imshow(np.angle(wf),
                        interpolation='none',
                        vmin=-np.pi,
                        vmax=np.pi,
                        cmap='hsv')
        ax2.set_xticks(tic_spacing)
        ax2.set_xticklabels(tic_labels)
        ax2.set_yticks(tic_spacing)
        ax2.set_yticklabels(tic_labels)
        ax2.set_ylabel(axlabel, fontsize=8)
        add_colorbar(im)

    if kwargs['verbose'] and kwargs['ix'] == 0:
        print(
            f"\nFocal Plane\n"
            f"sampling at focal plane is {samp*1e6:.1f} um ~= {smp_asec * 1e3:.4f} mas\n"
            f"\tfull FOV is {samp * kwargs['psf_size'][0] * 1e3:.2f} x {samp * kwargs['psf_size'][1] * 1e3:.2f} mm "
        )
        # s_rad = proper.prop_get_sampling_radians(wfo)
        # print(f"sampling at focal plane is {s_rad * 1e6:.6f} urad")
        print(f'final focal ratio is {proper.prop_get_fratio(wfo)}')

        print(f"Finished simulation")

    return wf, samp
예제 #20
0
def lyotstop(wf, diam, r_obstr, npupil, RAVC, LS, LS_parameters, spiders_angle, LS_phase_apodizer_file, LS_amplitude_apodizer_file, LS_misalignment, path, Debug_print, Debug):

    if (RAVC==True): # define the inner radius of the Lyot Stop
        t1_opt = 1. - 1./4*(r_obstr**2 + r_obstr*(math.sqrt(r_obstr**2 + 8.))) # define the apodizer transmission [Mawet2013]
        R1_opt = (r_obstr/math.sqrt(1. - t1_opt)) # define teh apodizer radius [Mawet2013]
        r_LS = R1_opt + LS_parameters[1] # when a Ring apodizer is present, the inner LS has to have at least the value of the apodizer radius
    else:
        r_LS = r_obstr + LS_parameters[1] # when no apodizer, the LS has to have at least the radius of the pupil central obstruction
    if LS==True: # apply the LS
        if (Debug_print==True):
            print("LS parameters: ", LS_parameters)
        proper.prop_circular_aperture(wf, LS_parameters[0], LS_misalignment[0], LS_misalignment[1], NORM=True)
        proper.prop_circular_obscuration(wf, r_LS, LS_misalignment[0], LS_misalignment[1], NORM=True)
        if (LS_parameters[2]!=0):
            for iter in range(0,len(spiders_angle)):
                if (Debug_print==True):
                    print("LS_misalignment: ", LS_misalignment)
                proper.prop_rectangular_obscuration(wf, LS_parameters[2], 2*diam,LS_misalignment[0], LS_misalignment[1], ROTATION=spiders_angle[iter]) # define the spiders

    
    if (isinstance(LS_phase_apodizer_file, (list, tuple, np.ndarray)) == True):
        xc_pixels = int(LS_misalignment[3]*npupil)
        yc_pixels = int(LS_misalignment[4]*npupil)
        apodizer_pixels = (LS_phase_apodizer_file.shape)[0]## fits file size
        scaling_factor = float(npupil)/float(pupil_pixels) ## scaling factor between the fits file size and the pupil size of the simulation
        if (Debug_print==True):
            print ("scaling_factor: ", scaling_factor)
        apodizer_scale = cv2.resize(phase_apodizer_file.astype(np.float32), (0,0), fx=scaling_factor, fy=scaling_factor, interpolation=cv2.INTER_LINEAR) # scale the pupil to the pupil size of the simualtions
        if (Debug_print==True):
            print ("apodizer_resample", apodizer_scale.shape)
        apodizer_large = np.zeros((n,n)) # define an array of n-0s, where to insert the pupuil
        if (Debug_print==True):
            print("n: ", n)
            print("npupil: ", npupil)
        apodizer_large[int(n/2)+1-int(npupil/2)-1 + xc_pixels:int(n/2)+1+int(npupil/2)+ xc_pixels,int(n/2)+1-int(npupil/2)-1+ yc_pixels:int(n/2)+1+int(npupil/2)+ yc_pixels] =apodizer_scale # insert the scaled pupil into the 0s grid
        phase_multiply = np.array(np.zeros((n,n)), dtype=complex) # create a complex array
        phase_multiply.imag = apodizer_large # define the imaginary part of the complex array as the atm screen
        apodizer = np.exp(phase_multiply)
        proper.prop_multiply(wf, apodizer)
        if (Debug == True):
            fits.writeto(path + 'LS_apodizer.fits', proper.prop_get_phase(wf), overwrite=True)

    
    
    if (isinstance(LS_amplitude_apodizer_file, (list, tuple, np.ndarray)) == True):
        xc_pixels = int(LS_misalignment[0]*npupil)
        yc_pixels = int(LS_misalignment[1]*npupil)
        apodizer_pixels = (LS_amplitude_apodizer_file.shape)[0]## fits file size
        scaling_factor = float(npupil)/float(pupil_pixels) ## scaling factor between the fits file size and the pupil size of the simulation
        if (Debug_print==True):
            print ("scaling_factor: ", scaling_factor)
            apodizer_scale = cv2.resize(amplitude_apodizer_file.astype(np.float32), (0,0), fx=scaling_factor, fy=scaling_factor, interpolation=cv2.INTER_LINEAR) # scale the pupil to the pupil size of the simualtions
        if (Debug_print==True):
            print ("apodizer_resample", apodizer_scale.shape)
        apodizer_large = np.zeros((n,n)) # define an array of n-0s, where to insert the pupuil
        if (Debug_print==True):
            print("n: ", n)
            print("npupil: ", npupil)
        apodizer_large[int(n/2)+1-int(npupil/2)-1 + xc_pixels:int(n/2)+1+int(npupil/2)+ xc_pixels,int(n/2)+1-int(npupil/2)-1+ yc_pixels:int(n/2)+1+int(npupil/2)+ yc_pixels] =apodizer_scale # insert the scaled pupil into the 0s grid
        apodizer = apodizer_large
        proper.prop_multiply(wf, apodizer)
        if (Debug == True):
            fits.writeto(path + 'LS_apodizer.fits', proper.prop_get_amplitude(wf), overwrite=True)





    return
예제 #21
0
def telescope(
    wavelength,
    gridsize,
    PASSVALUE={
        'prefix': 'prova',
        'path': os.path.abspath(os.path.join(__file__, os.pardir)),
        'charge': 0,
        'CAL': 0,
        'diam': 37.,
        'spiders_width': 0.60,
        'spiders_angle': [0., 60., 120.],
        'beam_ratio': 0.25,
        'f_lens': 658.6,
        'npupil': 243,
        'r_obstr': 0.3,
        'pupil_file': 0,
        'phase_apodizer_file': 0,
        'amplitude_apodizer_file': 0,
        'TILT': [0., 0.],
        'LS': False,
        'RAVC': False,
        'LS_phase_apodizer_file': 0,
        'LS_amplitude_apodizer_file': 0,
        'LS_parameters': [0.0, 0.0, 0.0],
        'atm_screen': 0,
        'missing_segments_number': 0,
        'apodizer_misalignment': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
        'LS_misalignment': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
        'Island_Piston': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
        'NCPA': 0,
        'Debug_print': False,
        'Debug': False
    }):

    ## call all the vues passed via passvalue
    prefix = PASSVALUE['prefix']
    path = PASSVALUE['path']
    charge = PASSVALUE['charge']
    CAL = PASSVALUE['CAL']
    diam = PASSVALUE['diam']
    spiders_width = PASSVALUE['spiders_width']
    spiders_angle = PASSVALUE['spiders_angle']
    beam_ratio = PASSVALUE['beam_ratio']
    f_lens = PASSVALUE['f_lens']
    npupil = PASSVALUE['npupil']
    r_obstr = PASSVALUE['r_obstr']
    pupil_file = PASSVALUE['pupil_file']
    phase_apodizer_file = PASSVALUE['phase_apodizer_file']
    amplitude_apodizer_file = PASSVALUE['amplitude_apodizer_file']
    TILT = PASSVALUE['TILT']
    LS = PASSVALUE['LS']
    RAVC = PASSVALUE['RAVC']
    LS_phase_apodizer_file = PASSVALUE['LS_phase_apodizer_file']
    LS_amplitude_apodizer_file = PASSVALUE['LS_amplitude_apodizer_file']
    LS_parameters = PASSVALUE['LS_parameters']
    atm_screen = PASSVALUE['atm_screen']
    missing_segments_number = PASSVALUE['missing_segments_number']
    apodizer_misalignment = PASSVALUE['apodizer_misalignment']
    LS_misalignment = PASSVALUE['LS_misalignment']
    Island_Piston = PASSVALUE['Island_Piston']
    NCPA = PASSVALUE['NCPA']
    Debug_print = PASSVALUE['Debug_print']
    Debug = PASSVALUE['Debug']

    TILT = np.array(TILT)
    apodizer_misalignment = np.array(apodizer_misalignment)
    LS_misalignment = np.array(LS_misalignment)
    Island_Piston = np.array(Island_Piston)

    ## call the size of the grid
    n = int(gridsize)

    wfo = proper.prop_begin(diam, wavelength, gridsize,
                            beam_ratio)  # define the simualtion pupil
    lamda = proper.prop_get_wavelength(
        wfo)  #save the wavelength value [m] into lamda

    if (Debug_print == True):
        print("lambda: ", lamda)

    pupil(wfo, CAL, npupil, diam, r_obstr, spiders_width, spiders_angle,
          pupil_file, missing_segments_number, Debug, Debug_print)

    if (Debug == True):
        fits.writeto(
            path + prefix + '_pupil_pre_define.fits',
            proper.prop_get_amplitude(wfo)[int(n / 2) -
                                           int(npupil / 2 + 50):int(n / 2) +
                                           int(npupil / 2 + 50),
                                           int(n / 2) -
                                           int(npupil / 2 + 50):int(n / 2) +
                                           int(npupil / 2 + 50)],
            overwrite=True)

    proper.prop_define_entrance(wfo)  #define the entrance wavefront

    #wfo.wfarr *= 1./np.amax(wfo._wfarr) # max(amplitude)=1

    if (isinstance(atm_screen, (list, tuple, np.ndarray)) == True) and (
            atm_screen.ndim >= 2):  # when the atmosphere is present
        print('atmosphere')
        atmosphere(wfo, npupil, atm_screen, Debug_print, Debug)

    if (isinstance(NCPA, (list, tuple, np.ndarray))
            == True) and (NCPA.ndim >= 2):  # when the atmosphere is present
        NCPA_application(wfo, npupil, NCPA, path, Debug_print, Debug)

    if (RAVC
            == True) or (isinstance(phase_apodizer_file,
                                    (list, tuple, np.ndarray))
                         == True) or (isinstance(amplitude_apodizer_file,
                                                 (list, tuple, np.ndarray))
                                      == True):  # when tha apodizer is present
        apodization(wfo, r_obstr, npupil, RAVC, phase_apodizer_file,
                    amplitude_apodizer_file, apodizer_misalignment,
                    Debug_print, Debug)

    if (all(v == 0
            for v in Island_Piston) == False):  # when the piston is present
        island_effect_piston(wfo, npupil, Island_Piston, path, Debug_print,
                             Debug)

    if (TILT.any != 0.):  # when tip/tilt
        if (Debug_print == True):
            print("TILT: ", TILT)
            print("lamda: ", lamda)
        tiptilt = (np.multiply(
            TILT, lamda
        )) / 4  # translate the tip/tilt from lambda/D into RMS phase errors
        proper.prop_zernikes(wfo, [2, 3], tiptilt)  # 2-->xtilt, 3-->ytilt

    if (Debug == True):
        if CAL == 1:
            fits.writeto(path + prefix + '_pupil_amplitude_CAL1.fits',
                         proper.prop_get_amplitude(wfo)
                         [int(n / 2) - int(npupil / 2 + 50):int(n / 2) +
                          int(npupil / 2 + 50),
                          int(n / 2) - int(npupil / 2 + 50):int(n / 2) +
                          int(npupil / 2 + 50)],
                         overwrite=True)
            fits.writeto(
                path + prefix + '_pupil_phase_CAL1.fits',
                proper.prop_get_phase(wfo)[int(n / 2) -
                                           int(npupil / 2 + 50):int(n / 2) +
                                           int(npupil / 2 + 50),
                                           int(n / 2) -
                                           int(npupil / 2 + 50):int(n / 2) +
                                           int(npupil / 2 + 50)],
                overwrite=True)
        else:
            fits.writeto(
                path + prefix + '_pupil_amplitude_CAL0_RA' + str(int(RAVC)) +
                '_charge' + str(charge) + '_ATM' + str(
                    int(
                        isinstance(atm_screen, (list, tuple,
                                                np.ndarray)) == True)) +
                '.fits',
                proper.prop_get_amplitude(
                    wfo)[int(n / 2) - int(npupil / 2 + 50):int(n / 2) +
                         int(npupil / 2 + 50),
                         int(n / 2) - int(npupil / 2 + 50):int(n / 2) +
                         int(npupil / 2 + 50)],
                overwrite=True)
            fits.writeto(
                path + prefix + '_pupil_phase_CAL0_RA' + str(int(RAVC)) +
                '_charge' + str(charge) + '_ATM' + str(
                    int(
                        isinstance(atm_screen, (list, tuple,
                                                np.ndarray)) == True)) +
                '.fits',
                proper.prop_get_phase(wfo)[int(n / 2) -
                                           int(npupil / 2 + 50):int(n / 2) +
                                           int(npupil / 2 + 50),
                                           int(n / 2) -
                                           int(npupil / 2 + 50):int(n / 2) +
                                           int(npupil / 2 + 50)],
                overwrite=True)

    proper.prop_propagate(wfo, f_lens, 'inizio')  # propagate wavefront

    proper.prop_lens(wfo, f_lens,
                     'focusing lens vortex')  # propagate through a lens
    proper.prop_propagate(wfo, f_lens, 'VC')  # propagate wavefront

    vortex(wfo, CAL, charge, f_lens, path, Debug_print)

    if (Debug == True):
        if CAL == 1:
            fits.writeto(path + prefix + '_afterVortex_CAL1.fits',
                         proper.prop_get_amplitude(wfo)
                         [int(n / 2) - int(npupil / 2 + 50):int(n / 2) +
                          int(npupil / 2 + 50),
                          int(n / 2) - int(npupil / 2 + 50):int(n / 2) +
                          int(npupil / 2 + 50)],
                         overwrite=True)
            fits.writeto(
                path + prefix + '_afterVortex_CAL1_phase.fits',
                proper.prop_get_phase(wfo)[int(n / 2) -
                                           int(npupil / 2 + 50):int(n / 2) +
                                           int(npupil / 2 + 50),
                                           int(n / 2) -
                                           int(npupil / 2 + 50):int(n / 2) +
                                           int(npupil / 2 + 50)],
                overwrite=True)
        else:
            print(
                'ATM: ',
                str(
                    int(
                        isinstance(atm_screen, (list, tuple,
                                                np.ndarray)) == True)))
            if ((((int(
                    isinstance(atm_screen, (list, tuple,
                                            np.ndarray)) == True)))) == 1):
                print('atm_screen: ', atm_screen.shape)
                print(
                    'ATM: ',
                    int(
                        isinstance(atm_screen, (list, tuple,
                                                np.ndarray)) == True))
            fits.writeto(
                path + prefix + '_afterVortex_CAL0_RA' + str(int(RAVC)) +
                '_charge' + str(charge) + '_ATM' + str(
                    int(
                        isinstance(atm_screen, (list, tuple,
                                                np.ndarray)) == True)) +
                '.fits',
                proper.prop_get_amplitude(
                    wfo)[int(n / 2) - int(npupil / 2 + 50):int(n / 2) +
                         int(npupil / 2 + 50),
                         int(n / 2) - int(npupil / 2 + 50):int(n / 2) +
                         int(npupil / 2 + 50)],
                overwrite=True)
            fits.writeto(
                path + prefix + '_afterVortex_phase_CAL0_RA' + str(int(RAVC)) +
                '_charge' + str(charge) + '_ATM' + str(
                    int(
                        isinstance(atm_screen, (list, tuple,
                                                np.ndarray)) == True)) +
                '.fits',
                proper.prop_get_phase(wfo)[int(n / 2) -
                                           int(npupil / 2 + 50):int(n / 2) +
                                           int(npupil / 2 + 50),
                                           int(n / 2) -
                                           int(npupil / 2 + 50):int(n / 2) +
                                           int(npupil / 2 + 50)],
                overwrite=True)

    proper.prop_propagate(wfo, f_lens,
                          'Lyot Collimetor')  # propagate wavefront

    proper.prop_lens(wfo, f_lens,
                     'Lyot Collimetor')  # propagate wavefront through  a lens
    proper.prop_propagate(wfo, f_lens, 'Lyot Stop')  # propagate wavefront

    if (Debug == True):
        if CAL == 1:
            fits.writeto(path + prefix + '_beforeLS_CAL1.fits',
                         proper.prop_get_amplitude(wfo)
                         [int(n / 2) - int(npupil / 2 + 50):int(n / 2) +
                          int(npupil / 2 + 50),
                          int(n / 2) - int(npupil / 2 + 50):int(n / 2) +
                          int(npupil / 2 + 50)],
                         overwrite=True)
        else:
            fits.writeto(
                path + prefix + '_beforeLS_CAL0_charge' + str(charge) +
                '_ATM' + str(
                    int(
                        isinstance(atm_screen, (list, tuple,
                                                np.ndarray)) == True)) +
                '.fits',
                proper.prop_get_amplitude(
                    wfo)[int(n / 2) - int(npupil / 2 + 50):int(n / 2) +
                         int(npupil / 2 + 50),
                         int(n / 2) - int(npupil / 2 + 50):int(n / 2) +
                         int(npupil / 2 + 50)],
                overwrite=True)

    lyotstop(wfo, diam, r_obstr, npupil, RAVC, LS, LS_parameters,
             spiders_angle, LS_phase_apodizer_file, LS_amplitude_apodizer_file,
             LS_misalignment, path, Debug_print, Debug)

    if (Debug == True):
        if CAL == 1:
            fits.writeto(path + prefix + '_afterLS_CAL1.fits',
                         proper.prop_get_amplitude(wfo)
                         [int(n / 2) - int(npupil / 2 + 50):int(n / 2) +
                          int(npupil / 2 + 50),
                          int(n / 2) - int(npupil / 2 + 50):int(n / 2) +
                          int(npupil / 2 + 50)],
                         overwrite=True)
        else:
            fits.writeto(
                path + prefix + '_afterLS_CAL0_charge' + str(charge) + '_LS' +
                str(int(LS)) + '_RA' + str(int(RAVC)) + '_ATM' + str(
                    int(
                        isinstance(atm_screen, (list, tuple,
                                                np.ndarray)) == True)) +
                '.fits',
                proper.prop_get_amplitude(
                    wfo)[int(n / 2) - int(npupil / 2 + 50):int(n / 2) +
                         int(npupil / 2 + 50),
                         int(n / 2) - int(npupil / 2 + 50):int(n / 2) +
                         int(npupil / 2 + 50)],
                overwrite=True)

    proper.prop_propagate(wfo, f_lens)  # propagate wavefront

    proper.prop_lens(wfo, f_lens)  # propagate wavefront through a lens
    proper.prop_propagate(wfo, f_lens)  # propagate wavefront

    (wfo, sampling) = proper.prop_end(
        wfo, NOABS=True
    )  # conclude the simulation --> noabs= the wavefront array will be complex

    return (wfo, sampling)  # return the wavefront
예제 #22
0
def get_intensity(wf_array,
                  sp,
                  logAmp=True,
                  show=False,
                  save=True,
                  phase=False):

    if show == True:
        wfo = wf_array[0, 0]
        after_dm = proper.prop_get_amplitude(wfo)
        phase_afterdm = proper.prop_get_phase(wfo)

        fig = plt.figure(figsize=(14, 10))
        ax1 = plt.subplot2grid((3, 2), (0, 0), rowspan=2)
        ax2 = plt.subplot2grid((3, 2), (0, 1), rowspan=2)
        ax3 = plt.subplot2grid((3, 2), (2, 0))
        ax4 = plt.subplot2grid((3, 2), (2, 1))
        if logAmp:
            ax1.imshow(after_dm,
                       origin='lower',
                       cmap="YlGnBu_r",
                       norm=LogNorm())
        else:
            ax1.imshow(after_dm, origin='lower', cmap="YlGnBu_r")
        ax2.imshow(phase_afterdm, origin='lower',
                   cmap="YlGnBu_r")  #, vmin=-0.5, vmax=0.5)

        ax3.plot(after_dm[int(tp.grid_size / 2)])
        ax3.plot(np.sum(np.eye(tp.grid_size) * after_dm, axis=1))

        # plt.plot(np.sum(after_dm,axis=1)/after_dm[128,128])

        ax4.plot(phase_afterdm[int(tp.grid_size / 2)])
        # ax4.plot(np.sum(np.eye(tp.grid_size)*phase_afterdm,axis=1))
        plt.xlim([0, proper.prop_get_gridsize(wfo)])
        fig.set_tight_layout(True)

        plt.show()

    if save:
        shape = wf_array.shape
        ws = sp.get_ints['w']
        cs = sp.get_ints['c']

        int_maps = np.empty((0, tp.grid_size, tp.grid_size))
        for iw in ws:
            for iwf in cs:
                # int_maps.append(proper.prop_shift_center(np.abs(wf_array[iw, iwf].wfarr) ** 2))
                if phase:
                    int_map = proper.prop_get_phase(wf_array[iw, iwf])

                # int_map = proper.prop_shift_center(np.abs(wf_array[iw, iwf].wfarr) ** 2)
                else:
                    int_map = proper.prop_shift_center(
                        np.abs(wf_array[iw, iwf].wfarr)**2)
                int_maps = np.vstack((int_maps, [int_map]))
                # quicklook_im(int_map)#, logAmp=True)

        # int_maps = np.array(int_maps)
        # view_datacube(int_maps)
        import pickle, os
        if os.path.exists(iop.int_maps):
            # "with" statements are very handy for opening files.
            with open(iop.int_maps, 'rb') as rfp:
                # dprint(np.array(pickle.load(rfp)).shape)
                int_maps = np.vstack((int_maps, pickle.load(rfp)))

        with open(iop.int_maps, 'wb') as wfp:
            pickle.dump(int_maps, wfp, protocol=pickle.HIGHEST_PROTOCOL)