Exemplo n.º 1
0
def extract_spec(data, ebv=0, RV=3.1):

    mask = data["AND_MASK"].data > 0
    logwave_obs = data["LOGLAM"].astype(float).data
    spec = data["FLUX"].astype(float).data
    spec[mask] = np.nan
    spec_ivar = data["IVAR"].astype(float).data
    spec_ivar[mask] = np.nan
    spec_off = data["MODEL"].astype(float).data
    # spec = np.ma.masked_array(data["FLUX"].astype(float).data, mask=mask)
    # spec_off = np.ma.masked_array(data["MODEL"].astype(float).data, mask=mask)
    # spec_ivar = np.ma.masked_array(data["IVAR"].astype(float).data, mask=mask)

    if ebv > 0:
        extinction_sed = ebv * extinction.ccm89(
            10**logwave_obs, 1.0, RV, unit="aa")
        spec = extinction.remove(extinction_sed, spec)
        spec_off = extinction.remove(extinction_sed, spec_off)
        spec_ivar = extinction.apply(extinction_sed, spec_ivar)

    # ind = np.isfinite(logwave_obs)
    # ind &= np.isfinite(spec)
    # ind &= np.isfinite(spec_ivar)
    # ind &= np.isfinite(spec_off)

    return logwave_obs, spec, spec_ivar, spec_off
Exemplo n.º 2
0
def UVExcess_to_Mdot(UVexcess, bc, dist, mass, radius, Av, Rin=5):
    '''
    This function will transform a UV Excess flux value into a mass accretion rate estimate by following 
    the process described in Herczeg 2008. 
    
    Inputs:
    UVexcess - UV continuum excess flux [erg/(s*cm^2)]
    bc - bolometric correction
    dist - distance to object [pc]
    mass - mass of object [Msun]
    radius - radius of object [Rsun]
    
    Optional:
    Rin - magnetospheric radius (default 5 [Rsun])
    
    Outputs:
    Mdot - mass accretion rate [Msun/yr]
    '''
    #Extinction correction of flux
    deredUV = ex.remove(Av, UVexcess)

    #use the bolometric correction factor to scale the UV excess flux to total accretion flux
    total_excess = deredUV * bc

    #accretion flux to accretion luminosity
    Lacc = flux_to_luminosity(total_excess, dist)

    #convert accretion luminosity to solar luminosity
    Lacc = Lacc / const.L_sun.to('erg/s').value

    #accretion luminosity to Mdot
    Mdot = Lacc_to_Mdot(Lacc, mass, radius, Rin)

    return Mdot
Exemplo n.º 3
0
def deredden_spectrum(wave, flux, ebv, r_v=3.1, unit='aa', model='fm07'):
    """Deredden a spectrum based on a Galactic extinction model."""

    model = model.lower().strip()

    if model == 'fm07':
        mw_extinction = fm07(wave, ebv * r_v, unit=unit)
    elif model == 'ccm89':
        mw_extinction = ccm89(wave, ebv * r_v, r_v, unit=unit)
    elif model == 'odonnell94':
        mw_extinction = ccm89(wave, ebv * r_v, r_v, unit=unit)
    else:
        raise Exception(
            "# Wrong choice of extinction model: fm07/ccm89/odonnell94")

    return remove(mw_extinction, flux)
Exemplo n.º 4
0
def UbandExcess_to_Mdot(Uexcess, dist, mass, radius, Av, Rin=5, unc=False):
    '''
    This function will transform a U band flux value into a mass accretion rate estimate by following 
    the process described in Robinson 2019. 
    
    Inputs:
    Uexcess - U band continuum excess flux [erg/(s*cm^2)]
    dist - distance to object [pc]
    mass - mass of object [Msun]
    radius - radius of object [Rsun]
    
    Optional:
    Rin - magnetospheric radius (default 5 [Rsun])
    
    Outputs:
    Mdot - mass accretion rate [Msun/yr]
    '''
    #Extinction correction of flux
    #reddening law to U-band
    if type(Av) == float:
        Au = ex.ccm89(np.array([3650.0]), Av, 3.1)[0]
    elif type(Av) == list or type(Av) == np.ndarray:
        Au = []
        for av in Av:
            Au.append(ex.ccm89(np.array([3650.0]), av, 3.1)[0])
    Au = np.array(Au)
    #extinction correction
    deredU = ex.remove(Au, Uexcess)

    #U-band flux to Lu
    Lu = flux_to_luminosity(deredU, dist)

    #convert Lu to solar luminosity
    Lu = Lu / const.L_sun.to('erg/s').value

    #Lu to Lacc using Robinson paper -- natural logarithms
    #uncertainties 0.03 for each constant
    if unc == False:
        logLacc = 0.93 * np.log(Lu) + 0.5
    else:
        logLacc = (0.93 + np.random.normal(0.03)) * np.log(Lu) + (
            0.5 + np.random.normal(0.03))
    Lacc = np.exp(logLacc)

    #accretion luminosity to Mdot
    Mdot = Lacc_to_Mdot(Lacc, mass, radius, Rin)
    return Mdot
Exemplo n.º 5
0
def UVExcess_to_Mdot(UVexcess, bc, dist, mass, radius, Av, Rin=5):
    '''
    This function will transform a UV Excess flux value into a mass accretion rate estimate by following 
    the process described in Herczeg 2008. 
    
    Inputs:
    UVexcess - UV continuum excess flux [erg/(s*cm^2)]
    bc - bolometric correction
    dist - distance to object [pc]
    mass - mass of object [Msun]
    radius - radius of object [Rsun]
    
    Optional:
    Rin - magnetospheric radius (default 5 [Rsun])
    
    Outputs:
    Mdot - mass accretion rate [Msun/yr]
    '''
    #Extinction correction of flux
    #reddening law to U-band
    Au = Av
    if type(Av) == float:
        Au = ex.ccm89(np.array([3650.0]), Av, 3.1)[0]
    elif type(Av) == list or type(Av) == np.ndarray:
        Au = []
        for av in Av:
            Au.append(ex.ccm89(np.array([3650.0]), av, 3.1)[0])
    Au = np.array(Au)
    #extinction correction
    deredUV = ex.remove(Au, UVexcess)

    #use the bolometric correction factor to scale the UV excess flux to total accretion flux
    total_excess = deredUV * bc

    #accretion flux to accretion luminosity
    Lacc = flux_to_luminosity(total_excess, dist)

    #convert accretion luminosity to solar luminosity
    Lacc = Lacc / const.L_sun.to('erg/s').value

    #accretion luminosity to Mdot
    Mdot = Lacc_to_Mdot(Lacc, mass, radius, Rin)
    return Mdot
Exemplo n.º 6
0
def Spec_mags(Models, pbs, av=0, Rv=3.1, Conversion=1.029):
    """
    Generate synthetic magnitudes from the models and passbands added.
    Conversion converts between Ebv and Egr, the Green value is 0.981, but the best fit value
    was found to be 1.029.
    """
    #a_v = 3.1*(Conversion * ex ) # ex = extinction from Bayestar19 = Egr
    keys = list(pbs.keys())
    mags = {}
    for key in keys:
        mags[key] = []

        pb, zp = pbs[key]

        # construct mags
        ind = []
        red = {}
        for model in Models:
            if av > 0:
                model = S.ArraySpectrum(model.wave,
                                        apply(
                                            fitzpatrick99(model.wave, av, Rv),
                                            model.flux),
                                        waveunits=model.waveunits,
                                        fluxunits=model.fluxunits)
            if av < 0:
                model = S.ArraySpectrum(model.wave,
                                        remove(
                                            fitzpatrick99(model.wave, -av, Rv),
                                            model.flux),
                                        waveunits=model.waveunits,
                                        fluxunits=model.fluxunits)
            mags[key] += [source_synphot.passband.synphot(model, pb, zp)]

    for key in keys:
        mags[key] = np.array(mags[key])

    #good = np.ones(len(mags[key])) > 0
    #for key in keys:
    #    good = good *np.isfinite(mags[key])
    #for key in keys:
    #    mags[key] = mags[key][good]
    return mags
Exemplo n.º 7
0
def deredden(wave,
             flux,
             ra,
             dec,
             scaling=0.86,
             reddening_law='fitzpatrick99',
             dustmaps_dir=None,
             r_v=3.1,
             ebv=None):
    """Dereddens the given spectrum, given a right ascension and declination or :math:`E(B-V)`.

    Parameters
    ----------
    wave : array
        Wavelength values.
    flux : array
        Flux density values.
    ra : float
        Right ascension in degrees.
    dec : float
        Declination in degrees.
    scaling: float, default ``0.86``
        Calibration of the Milky Way dust maps. Either ``0.86``
        for the Schlafly & Finkbeiner (2011) recalibration or ``1.0`` for the original
        dust map of Schlegel, Fikbeiner & Davis (1998).
    reddening_law: str, default ``fitzpatrick99``
        Reddening law. The options are: ``ccm89`` (Cardelli, Clayton & Mathis 1989), ``odonnell94`` (O’Donnell 1994),
        ``fitzpatrick99`` (Fitzpatrick 1999), ``calzetti00`` (Calzetti 2000) and ``fm07`` (Fitzpatrick & Massa 2007 with
        :math:`R_V` = 3.1.)
    dustmaps_dir : str, default ``None``
        Directory where the dust maps of Schlegel, Fikbeiner & Davis (1998) are found.
    r_v : float, default ``3.1``
        Total-to-selective extinction ratio (:math:`R_V`)
    ebv : float, default ``None``
        Colour excess (:math:`E(B-V)`). If given, this is used instead of the dust map value.

    Returns
    -------
    deredden_flux : array
        Deredden flux values.

    """
    pisco_path = piscola.__path__[0]
    if dustmaps_dir is None:
        dustmaps_dir = os.path.join(pisco_path, 'sfddata-master')

    if ebv is None:
        m = sfdmap.SFDMap(mapdir=dustmaps_dir, scaling=scaling)
        ebv = m.ebv(ra, dec)  # RA and DEC in degrees

    a_v = r_v * ebv

    rl_list = ['ccm89', 'odonnell94', 'fitzpatrick99', 'calzetti00', 'fm07']
    assert reddening_law in rl_list, f'Choose one of the available reddening laws: {rl_list}'

    if reddening_law == 'ccm89':
        ext = extinction.ccm89(wave, a_v, r_v)
    elif reddening_law == 'odonnell94':
        ext = extinction.odonnell94(wave, a_v, r_v)
    elif reddening_law == 'fitzpatrick99':
        ext = extinction.fitzpatrick99(wave, a_v, r_v)
    elif reddening_law == 'calzetti00':
        ext = extinction.calzetti00(wave, a_v, r_v)
    elif reddening_law == 'fm07':
        ext = extinction.fm07(wave, a_v)

    deredden_flux = extinction.remove(ext, flux)

    return deredden_flux
Exemplo n.º 8
0
def lineflux_to_Mdot(flux,
                     dist,
                     mass,
                     radius,
                     Av,
                     Rin=5,
                     line=None,
                     A=None,
                     B=None):
    '''
    This function will turn a line flux into a mass accretion rate estimate using the Lacc-Lline fits derived
    by Alcala et al 2017. 
    
    Inputs:
    flux (float) : line flux [erg/(s*cm^2)]?
    dist (float) : distance to object [pc]
    mass (float) : mass of object [Msun]
    radius (float) : radius of object [Rsun]
    
    Optional:
    Rin (float) : magnetospheric radius (default 5 [Rsun])
    line (str) : type of line. for now acceptable inputs are H-alpha: 'Ha', Pa-beta: 'Pab', and Br-gamma: 'Brg'
    A (float) : If you want to input the parameters for your own line flux vs Lacc relationship
    B (float) : If you want to input the parameters for your own line flux vs Lacc relationship
    
    Outputs:
    Mdot (float) : mass accretion rate [Msun/yr]
    '''

    #a & b values pulled directly from the paper

    if line == None:
        a = A
        b = B
    elif line == 'Ha':
        a = 1.13  #+/- 0.05
        b = 1.74  #+/- 0.19
    elif line == 'Pab':
        a = 1.06  #+/- 0.07
        b = 2.76  #+/- 0.34
    elif line == 'Brg':
        a = 1.19  #+/- 0.10
        b = 4.02  #+/- 0.51
    else:
        print('Line not found.')
        return

    #extinction correction
    deredflux = ex.remove(Av, flux)

    #find Lline in erg/s
    Lline = deredflux * (4 * np.pi * (dist * const.pc.to('cm').value)**2)

    #convert to solar luminosity
    Lline = Lline / const.L_sun.to('erg/s').value

    #Find Lacc using Alcala relationships
    logLacc = a * np.log10(Lline) + b
    #solar luminosity
    Lacc = unlog(logLacc)

    Mdot = Lacc_to_Mdot(Lacc, mass, radius, Rin=Rin)

    return Mdot
Exemplo n.º 9
0
	def deredden(self,R_v=3.1):
		"""Deredden the spectrum, based on the estimated A_v, using the Fitzpatrick (1999) curve, as used in Schlafy & Finkbeiner (2012)"""
		self.data = self.data.T
		self.data[1] = remove(f99(self.data[0],self.A_v,R_v),self.data[1])
		self.data[2] = remove(f99(self.data[0],self.A_v,R_v),self.data[2])
		self.data = self.data.T
Exemplo n.º 10
0
        # "integrated" over the filter filter_bandwidth
        flux_bp = "int_flux(%s)" % (photflam.unit * rect_width.unit)
        phot_source[flux_bp] = phot_source[aperture_keyword] * photflam * rect_width
        phot_source["int_flux_err"] = phot_source_conf_pos * photflam * rect_width - phot_source[flux_bp]
        # more appropiate for emission lines
        line_flux = "monochromatic_flux(%s)" % (photflam.unit)
        phot_source[line_flux] = phot_source[aperture_keyword] * bp.emflx(bp.area)
        phot_source["monochromatic_flux_err"] = phot_source_conf_pos * bp.emflx(bp.area) - phot_source[line_flux]
        #https://www.stsci.edu/hst/instrumentation/acs/data-analysis/zeropoints
        phot_source["mag"] = -2.5 * log10(phot_source[aperture_keyword]) - zero_point
        phot_source["mag_err_neg"] = -2.5 * log10(phot_source_conf_pos) - zero_point - phot_source["mag"]
        phot_source["mag_err_pos"] = -2.5 * log10(phot_source_conf_neg) - zero_point - phot_source["mag"]

        if args.av is not None:
            waves = np.array([pivot_wavelength])
            phot_source["der_flux"] = remove(ccm89(waves, args.av, 3.1, unit="aa"), phot_source[flux_header])
            phot_source["der_flux_err"] = remove(ccm89(waves, args.av, 3.1, unit="aa"), phot_source_conf_pos* photflam ) - phot_source["der_flux"]

        # formatting
        phot_source["xcenter"].info.format = '%.2f'
        phot_source["ycenter"].info.format = '%.2f'
        phot_source["aperture_sum"].info.format = '%.3f'
        phot_source[aperture_keyword].info.format = '%.2f'
        phot_source["corrected_aperture_err"].info.format = '%.2f'
        phot_source[flux_header].info.format = '%.3E'
        phot_source['flux_err'].info.format = '%.2E'
        phot_source["mag"].info.format = "%.2f"
        phot_source["mag_err_neg"].info.format = "%.2f"
        phot_source["mag_err_pos"].info.format = "%.3f"
        reg_basename = os.path.basename(args.regions[0]).replace('.reg', '')
        out_data_file = "aperture_phot_%s_%s.csv" % (hst_filter, reg_basename)
Exemplo n.º 11
0
def test_sdss_halpha(fname,
                     fluxkey,
                     magkey,
                     magerrprefix,
                     bands,
                     scatter_density=True,
                     zkey="z",
                     xmin=-17,
                     xmax=-13,
                     output=None,
                     bands_ebv=None,
                     wline=6562.8 * u.AA):
    bands_ebv = ["G", "I"] if bands_ebv is None else bands_ebv
    ############################################################################
    # Reading transmission curves for S-PLUS
    filters_dir = os.path.join(os.getcwd(), "filter_curves-master")
    filenames = sorted([os.path.join(filters_dir, _) for _ in os.listdir( \
                        filters_dir)])
    filternames = [os.path.split(_)[1].replace(".dat", "") for _ in filenames]
    filternames = [
        _.replace("F0", "F").replace("JAVA", "") for _ in filternames
    ]
    filternames = [_.replace("SDSS", "").upper() for _ in filternames]
    fcurves = [np.loadtxt(f) for f in filenames]
    wcurves = [curve[:, 0] * u.AA for curve in fcurves]
    trans = [curve[:, 1] for curve in fcurves]
    wcurves = dict(zip(filternames, wcurves))
    trans = dict(zip(filternames, trans))
    halpha = EmLine3Filters(wline, [_.upper() for _ in bands], wcurves, trans)
    ############################################################################
    # Reading catalog and remove objects out of z-range
    wdir = os.path.join(context.home_dir, "catalogs")
    filename = os.path.join(wdir, fname)
    table = Table.read(filename)
    if zkey in table.colnames:
        table = table[table[zkey] < 0.02]
    ############################################################################
    # Cleaning table against large errors in mgnitudes
    magerrs = np.array([
        table["{}{}{}".format(magerrprefix, band, magkey)].data
        for band in bands
    ])
    idx = np.where(np.nanmax(magerrs, axis=0) < 0.2)[0]
    table = table[idx]
    ############################################################################
    # Estimating the extinction
    gi = np.array(
        [table["{}{}".format(band, magkey)].data for band in bands_ebv])
    g_i = gi[0] - gi[1]
    ebvs = np.clip(0.206 * np.power(g_i, 1.68) - 0.0457, 0, np.infty)
    Rv = 4.1
    Avs = Rv * ebvs
    corr = np.array([
        extinction.remove(
            extinction.calzetti00(np.atleast_1d(wline), Av, Rv)[0], 1)
        for Av in Avs
    ])
    ############################################################################
    # Correcting observations for Galactic extinction
    coords = SkyCoord(table["ra"] * u.degree, table["dec"] * u.degree)
    sfd = SFDQuery()
    ebv_mw = sfd(coords)
    Rv_mw = 3.1
    Av_mw = Rv_mw * ebv_mw
    corr_mw = np.array([
        extinction.remove(
            extinction.ccm89(halpha.wpiv, Av, Rv_mw)[0], np.ones(3))
        for Av in Av_mw
    ]).T
    ############################################################################
    # Calculating H-alpha
    mags = np.array(
        [table["{}{}".format(band, magkey)].data for band in bands])
    flam = mag2flux(mags, halpha.wpiv) * corr_mw
    flux_halpha_nii = halpha.flux_3F(flam)
    log_halpha = np.where(g_i <= 0.5,
                          0.989 * np.log10(flux_halpha_nii.value) - 0.193,
                          0.954 * np.log10(flux_halpha_nii.value) - 0.753)
    halpha_sdss = np.log10((table[fluxkey]) * np.power(10., -17))
    halpha_splus = log_halpha + np.log10(corr)
    ############################################################################
    # Selecting only regions within limits of flux
    idx = np.where(
        np.isfinite(halpha_sdss * halpha_splus) & (halpha_sdss > xmin)
        & (halpha_splus < xmax))
    halpha_sdss = halpha_sdss[idx]
    halpha_splus = halpha_splus[idx]
    ############################################################################
    fig = plt.figure()
    if scatter_density:
        ax = fig.add_subplot(1, 1, 1, projection='scatter_density')
        density = ax.scatter_density(halpha_sdss, halpha_splus, cmap="magma_r")
        fig.colorbar(density, label='Number of points per pixel')

    else:
        ax = fig.add_subplot(1, 1, 1)
        label = "mag_key={}".format(magkey)
        counts, xedges, yedges, im = ax.hist2d(halpha_sdss,
                                               halpha_splus,
                                               bins=(50, 50),
                                               cmap="bone_r")
        plt.legend(title=label)
        fig.colorbar(im, ax=ax)
    ax.set_aspect("equal")
    plt.xlim(xmin, xmax)
    plt.ylim(xmin, xmax)
    plt.plot(np.linspace(xmin, xmax, 100), np.linspace(xmin, xmax, 100), "--r")
    plt.xlabel(r"$\log$ H$\alpha$ (erg / s / cm$^2$) -- SDSS")
    plt.ylabel(r"$\log$ H$\alpha$ (erg / s / cm$^2$) -- SPLUS")
    axins = inset_axes(ax,
                       width="80%",
                       height="80%",
                       bbox_to_anchor=(.65, .05, .38, .38),
                       bbox_transform=ax.transAxes,
                       loc=3)
    diff = halpha_splus - halpha_sdss
    median = np.nanmedian(diff)
    std = np.nanstd(diff)
    title = "med: {:.2f} std: {:.2f}".format(median, std)
    axins.hist(diff, bins=20)
    axins.set_title(title)
    plt.tight_layout()
    if "output" is not None:
        plt.savefig(
            output,
            dpi=250,
        )
    plt.show()