Esempio n. 1
0
def test_show(filepath):
    hdu = fits.open(filepath)
    cube = hdu[0].data
    hdu.close()
    params_ami = {
        "peakmethod": 'fft',
        "bs_multi_tri": False,
        "maskname": "g7",
        "fw_splodge": 0.7,
    }
    bs = amical.extract_bs(cube,
                           filepath,
                           targetname='test',
                           **params_ami,
                           display=False)
    cal = amical.calibrate(bs, bs)
    amical.show(cal)
Esempio n. 2
0
def perform_calibrate(args):
    """Calibrate the data with AMICAL (save calibrated oifits files)"""

    sciname, calname = _select_association_file(args)
    bs_t = amical.load_bs_hdf5(sciname)

    bs_c = []
    for x in calname:
        bs_c = amical.load_bs_hdf5(x)

    display = len(bs_c) > 1
    cal = amical.calibrate(
        bs_t,
        bs_c,
        clip=args.clip,
        normalize_err_indep=args.norm,
        apply_atmcorr=args.atmcorr,
        apply_phscorr=args.phscorr,
        display=display,
    )

    # Position angle from North to East
    pa = bs_t.infos.pa

    cprint("\nPosition angle computed for the data: pa = %2.3f deg" % pa,
           "cyan")

    # Display and save the results as oifits
    if args.plot:
        amical.show(cal, true_flag_t3=False, cmax=180, pa=pa)
        plt.show()

    oifits_file = Path(bs_t.infos.filename).stem + "_calibrated.fits"

    amical.save(cal, oifits_file=oifits_file, datadir=args.outdir)
    return 0
Esempio n. 3
0
    "bs_multi_tri": False,
    "maskname": "g7",
    "fw_splodge": 0.7,
}

# Extract raw complex observables for the target and the calibrator:
# It's the core of the pipeline (amical/mf_pipeline/bispect.py)
bs_t = amical.extract_bs(cube_t,
                         file_t,
                         targetname="fakebinary",
                         **params_ami,
                         display=True)
bs_c = amical.extract_bs(cube_c,
                         file_c,
                         targetname="fakepsf",
                         **params_ami,
                         display=False)

# Calibrate the raw data to get calibrated V2 and CP.
# bs_c can be a single calibrator result or a list of calibrators.
# (see amical/calibration.py for details).
cal = amical.calibrate(bs_t, bs_c)

# Display and save the results as oifits
amical.show(cal)
dic = amical.save(cal,
                  oifits_file="example_fakebinary_NIRISS.oifits",
                  fake_obj=True)

plt.show(block=True)
Esempio n. 4
0
              }


# # Extract raw complex observables for the target and the calibrator:
# # It's the core of the pipeline (amical/mf_pipeline/bispect.py)
bs_t = amical.extract_bs(cube_t, file_t, targetname='HD142527',
                         **params_ami, display=True)
bs_c = amical.extract_bs(cube_c, file_c, targetname='HD142695',
                         **params_ami, display=False)

# (from amical.tools import check_seeing_cond, plot_seeing_cond)
# In case of multiple files for a same target, you can
# check the seeing condition and select only the good ones.
# cond_t = check_seeing_cond([bs_t])
# cond_c = check_seeing_cond([bs_c])
# plot_seeing_cond([cond_t, cond_c], lim_seeing=1)


# Calibrate the raw data to get get calibrated V2 and CP
# bs_c can be a single calibrator result or a list of calibrator.
# (see amical/core.py for details).
cal = amical.calibrate(bs_t, bs_c)


# Display and save the results as oifits
amical.show(cal, true_flag_t3=False, cmax=180, pa=0)  # bs_t.infos.pa)
# amical.save(cal, oifits_file='example_HD142527_SPHERE.oifits',
#             fake_obj=True, verbose=False, pa=bs_t.infos.pa)

plt.show(block=True)
Esempio n. 5
0
def test_show(cal):
    amical.show(cal)
Esempio n. 6
0
def candid_binary_extraction(calib_oifits, mnemonic):
    """
    calib_oifits: full path file name of [calibrated, usually] oifits file
    This directory is where subdirectory of results are written (text, plots)
    using the oifits file name root
    mnemonic: short string to name output file plots - usually with eg HD #s or names of target_calibrator
    """

    outputfile = os.path.dirname(calib_oifits) + '/' + mnemonic

    # ***
    # These are the binary parameters we expect CANDID to extract
    sep = 363.04  # binary separation [mas]
    theta = 285.398112  # position angle (pa) [deg]
    dm = 4.2  # delta magnitude [mag]

    fits.info(calib_oifits)

    fits.getheader(calib_oifits)
    # Your input data is an oifits file
    with fits.open(calib_oifits) as hdu:
        cp_ext = hdu['OI_T3'].data
        sqvis_ext = hdu['OI_VIS2'].data
        oiarray = hdu['OI_ARRAY'].data
        wavel = hdu['OI_WAVELENGTH'].data['EFF_WAVE']
        pscale = hdu['OI_ARRAY'].header['PSCALE']
        pav3 = hdu[0].header['PA']
    print('Wavelength: %.2e m' % wavel)
    print('V3 PA: %.2f degrees' % pav3)
    cp = cp_ext['T3PHI']
    cp_err = cp_ext['T3PHIERR']
    tri_idx = cp_ext['STA_INDEX']

    sqvis = sqvis_ext['VIS2DATA']
    sqvis_err = sqvis_ext['VIS2ERR']
    bl_idx = sqvis_ext['STA_INDEX']

    hole_ctrs = oiarray['STAXYZ']
    hole_idx = oiarray['STA_INDEX']

    # Calculate the length of the baseline [m] for each pair
    baselines = []
    for bl in bl_idx:
        hole1, hole2 = (bl[0] - 1), (bl[1] - 1
                                     )  # because hole numbers start at 1
        x1, y1 = hole_ctrs[hole1][0], hole_ctrs[hole1][1]
        x2, y2 = hole_ctrs[hole2][0], hole_ctrs[hole2][1]
        length = np.abs(np.sqrt((x2 - x1)**2. + (y2 - y1)**2.))
        baselines.append(length)
    # Calculate the length of three baselines for each triangle
    # Select the longest for plotting
    tri_baselines = []
    tri_longest = []
    for tri in tri_idx:
        hole1, hole2, hole3 = tri[0] - 1, tri[1] - 1, tri[2] - 1
        x1, y1 = hole_ctrs[hole1][0], hole_ctrs[hole1][1]
        x2, y2 = hole_ctrs[hole2][0], hole_ctrs[hole2][1]
        x3, y3 = hole_ctrs[hole3][0], hole_ctrs[hole3][1]
        length12 = np.abs(np.sqrt((x2 - x1)**2. + (y2 - y1)**2.))
        length23 = np.abs(np.sqrt((x3 - x2)**2. + (y3 - y2)**2.))
        length31 = np.abs(np.sqrt((x1 - x3)**2. + (y1 - y3)**2.))
        tri_lengths = [length12, length23, length31]
        tri_baselines.append(tri_lengths)
        tri_longest.append(np.max(tri_lengths))

    # Calculate B_max/lambda
    bmaxlambda_sqvis = baselines / wavel
    bmaxlambda_cp = tri_longest / wavel

    # Label baselines and triangles
    bl_strings = []
    for idx in bl_idx:
        bl_strings.append(str(idx[0]) + '_' + str(idx[1]))

    tri_strings = []
    for idx in tri_idx:
        tri_strings.append(str(idx[0]) + '_' + str(idx[1]) + '_' + str(idx[2]))

    print(sorted(baselines))

    # Plot closure phases, square visibilities
    # Label which point corresponds to which hole pair or triple

    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(20, 7))
    ax1.errorbar(bmaxlambda_cp, cp, yerr=cp_err, fmt='go')
    ax1.set_xlabel(r'$B_{max}/\lambda$', size=16)
    ax1.set_ylabel('Closure phase [deg]', size=14)
    ax1.set_title('Calibrated Closure Phase', size=14)
    for ii, tri in enumerate(tri_strings):
        ax1.annotate(tri, (bmaxlambda_cp[ii], cp[ii]),
                     xytext=(bmaxlambda_cp[ii] + 10000, cp[ii]))

    ax2.errorbar(bmaxlambda_sqvis, sqvis, yerr=sqvis_err, fmt='go')
    ax2.set_title('Calibrated Squared Visibility', size=16)
    ax2.set_xlabel(r'$B_{max}/\lambda$', size=14)
    ax2.set_ylabel('Squared visibility amplitude', size=14)
    for ii, bl in enumerate(bl_strings):
        ax2.annotate(bl, (bmaxlambda_sqvis[ii], sqvis[ii]),
                     xytext=(bmaxlambda_sqvis[ii] + 10000, sqvis[ii]))
    plt.savefig(outputfile + "_cp_sqv.png")

    # The above plots show the calibrated closure phases (left) and the
    # calibrated squared visibilities (right). Each quantity is plotted against
    # $B_{max}/\lambda$, the baseline length divided by the wavelength of the
    # observation. In the case of closure phases, where the triangle is formed
    # by three baselines, the longest one is selected.
    #
    # For a monochromatic observation of a point source, we would expect all 35
    # closure phases to be zero, and all 21 squared visibilities to be unity.
    # Asymmetries in the target caused by, e.g., an unresolved companion, cause
    # the closure phases and visibilities corresponding to the baselines
    # between affected sub-apertures to diverge from zero or unity. We can now
    # use the set of calibrated observables to model the most probable location
    # and contrast ratio of the companion.

    # You can also use the dedicated tool from AMICAL to plot the data:

    plot = amical.show(calib_oifits, cmax=30)
    plt.savefig(outputfile + '_amical_show.png')

    bmax = 5.28 * u.meter
    wavel = 4.8e-6 * u.meter
    maxstep = wavel / (4 * bmax) * u.rad
    stepsize = int(maxstep.to(u.mas) / u.mas)
    print('Using a step size of %i mas' % stepsize)

    param_candid = {
        'rmin': 10,  # inner radius of the grid
        'rmax': 500,  # outer radius of the grid
        'step': stepsize,  # grid sampling
        'ncore': multiprocessing.cpu_count()  # core for multiprocessing
    }
    # Perform the fit
    fit1 = amical.candid_grid(calib_oifits,
                              **param_candid,
                              diam=0,
                              doNotFit=['diam*'],
                              save=True,
                              outputfile=outputfile)

    # plot the fitted model on data with residuals
    mod_v2, mod_cp, chi2 = amical.plot_model(calib_oifits,
                                             fit1['best'],
                                             save=True,
                                             outputfile=outputfile)

    # In the above output, CANDID provides a best-fit angular size for the
    # target star, 'best fit diameter (UD)', and the $\chi^2$ and n$\sigma$
    # (capped at 50$\sigma$) of the detection. It gives us estimates for the
    # binary separation ('sep'), position angle ('theta'), contrast ratio
    # ('CR'), and delta magnitudes ('dm').
    #
    # It also produces plots of the squared visibilities and closure phases,
    # and plots the residual (difference between the data and the best-fit
    # model for each observable).
    #
    # We can now compare these with our expected values from above:

    sep_fit, sep_unc = fit1['best']['sep'], fit1['uncer']['sep']
    theta_fit, theta_unc = fit1['best']['theta'], fit1['uncer']['theta']
    dm_fit, dm_unc = fit1['best']['dm'], fit1['uncer']['dm']

    print('             Expected      Model')
    print('Sep [mas]:   %.3f      %.3f +/- %.2f' % (sep, sep_fit, sep_unc))
    print('Theta [deg]: %.3f      %.3f +/- %.2f' %
          (theta, theta_fit, theta_unc))
    print('dm [mag]:    %.3f        %.3f +/- %.2f' % (dm, dm_fit, dm_unc))

    # Next, we will use CANDID to find the detection limit at different angular
    # separations. To do this, CANDID injects an additional companion at each
    # grid position with different flux ratios and estimates the number of
    # sigma for a theoretical detection at that point. It interpolates the flux
    # ratio values at 3$\sigma$ for all points in the grid to produce a
    # 3$\sigma$ detection map of the contrast (flux) ratio.

    #  Find detection limits using the fake injection method
    cr_candid = amical.candid_cr_limit(calib_oifits,
                                       **param_candid,
                                       fitComp=fit1['comp'],
                                       save=True,
                                       outputfile=outputfile)
Esempio n. 7
0
def test_show(bss):
    bs = bss["fft"]
    cal = amical.calibrate(bs, bs)
    amical.show(cal)