Ejemplo n.º 1
0
    def get_spectrum(self, fname, gal_id, stype='out'):
        """
        For combined spec files
        """
        # if fname is None:
        #     run = glob.glob('{0}/snap*.galaxy*.rt{1}.sed'.format(directory,stype))
        # else:
        #     run = glob.glob('{0}/{1}'.format(directory,fname))

        # if len(run) > 1:
        #     raise ValueError('More than one spectrum in directory')
        # elif len(run) == 0:
        #     raise ValueError('No output spectrum in this directory')

        if gal_id is None:
            m = ModelOutput(filename=fname)
        else:
            m = ModelOutput(filename=fname, group=gal_id)
        wav, lum = m.get_sed(inclination='all', aperture=-1)

        # set units
        wav = np.asarray(wav) * u.micron
        lum = np.asarray(lum) * u.erg / u.s

        return (wav, lum)
Ejemplo n.º 2
0
def dump_data(pf,model):
    ad = pf.all_data()
    particle_fh2 = ad["gasfh2"]
    particle_fh1 = np.ones(len(particle_fh2))-particle_fh2
    particle_gas_mass = ad["gasmasses"]
    particle_star_mass = ad["starmasses"]
    particle_star_metallicity = ad["starmetals"]
    particle_stellar_formation_time = ad["starformationtime"]
    particle_sfr = ad['gassfr'].in_units('Msun/yr')

    #these are in try/excepts in case we're not dealing with gadget and yt 3.x
    try: grid_gas_mass = ad["gassmoothedmasses"]
    except: grid_gas_mass = -1
    try: grid_gas_metallicity = ad["gassmoothedmetals"]
    except: grid_gas_metallicity = -1
    try: grid_star_mass = ad["starsmoothedmasses"]
    except: grid_star_mass = -1

    #get tdust
    m = ModelOutput(model.outputfile+'.sed')
    oct = m.get_quantities()
    tdust_pf = oct.to_yt()
    tdust_ad = tdust_pf.all_data()
    tdust = tdust_ad[ ('gas', 'temperature')]


    try: outfile = cfg.model.PD_output_dir+"grid_physical_properties."+cfg.model.snapnum_str+'_galaxy'+cfg.model.galaxy_num_str+".npz"
    except:
        outfile = cfg.model.PD_output_dir+"grid_physical_properties."+cfg.model.snapnum_str+".npz"

    np.savez(outfile,particle_fh2=particle_fh2,particle_fh1 = particle_fh1,particle_gas_mass = particle_gas_mass,particle_star_mass = particle_star_mass,particle_star_metallicity = particle_star_metallicity,particle_stellar_formation_time = particle_stellar_formation_time,grid_gas_metallicity = grid_gas_metallicity,grid_gas_mass = grid_gas_mass,grid_star_mass = grid_star_mass,particle_sfr = particle_sfr,tdust = tdust)
Ejemplo n.º 3
0
def load_obs(sed_file):

    from hyperion.model import ModelOutput
    from astropy.cosmology import Planck15
    from astropy import units as u
    from astropy import constants
    m = ModelOutput(sed_file)

    wav,flux = m.get_sed(inclination='all',aperture=-1)
    wav  = np.asarray(wav)*u.micron #wav is in micron  
    wav = wav.to(u.AA)
    #wav *= (1.+2.)
    flux = np.asarray(flux)*u.erg/u.s
    dl = 10.0*u.pc
    #dl = Planck15.luminosity_distance(2.0)
    dl = dl.to(u.cm)
    flux /= (4.*3.14*dl**2.)
    nu = constants.c.cgs/(wav.to(u.cm))
    nu = nu.to(u.Hz)

    flux /= nu
    flux = flux.to(u.Jy)
    maggies = flux[0] / 3631.

    return maggies.value, wav
def get_image(filename, dist):
    try:
        m = ModelOutput(filename)
        return m.get_image(inclination='all',
                           distance=luminosity_distance,
                           units='Jy')
    except (OSError, ValueError) as e:
        print("OS Error in reading in: " + filename)
        pass
Ejemplo n.º 5
0
def build_obs(**kwargs):

    from hyperion.model import ModelOutput
    from astropy import units as u
    from astropy import constants
    print('galaxy: ', sys.argv[1])
    m = ModelOutput(
        "/ufrc/narayanan/s.lower/pd_runs/simba_m25n512/snap305_dustscreen/snap305/snap305.galaxy"
        + str(sys.argv[1]) + ".rtout.sed")
    wav, flux = m.get_sed(inclination=0, aperture=-1)
    wav = np.asarray(wav) * u.micron  #wav is in micron
    wav = wav.to(u.AA)
    flux = np.asarray(flux) * u.erg / u.s
    dl = (10. * u.pc).to(u.cm)
    flux /= (4. * 3.14 * dl**2.)
    nu = constants.c.cgs / (wav.to(u.cm))
    nu = nu.to(u.Hz)
    flux /= nu
    flux = flux.to(u.Jy)
    maggies = flux / 3631.

    filters_unsorted = load_filters(filternames)
    waves_unsorted = [x.wave_mean for x in filters_unsorted]
    filters = [x for _, x in sorted(zip(waves_unsorted, filters_unsorted))]
    flx = []
    flxe = []

    for i in range(len(filters)):
        flux_range = []
        wav_range = []
        for j in filters[i].wavelength:
            flux_range.append(maggies[find_nearest(wav.value, j)].value)
            wav_range.append(wav[find_nearest(wav.value, j)].value)
        a = np.trapz(wav_range * filters[i].transmission * flux_range,
                     wav_range,
                     axis=-1)
        b = np.trapz(wav_range * filters[i].transmission, wav_range)
        flx.append(a / b)
        flxe.append(0.03 * flx[i])

    flx = np.asarray(flx)
    flxe = np.asarray(flxe)
    flux_mag = flx
    unc_mag = flxe

    obs = {}
    obs['filters'] = filters
    obs['maggies'] = flux_mag
    obs['maggies_unc'] = unc_mag
    obs['phot_mask'] = np.isfinite(flux_mag)
    obs['wavelength'] = None
    obs['spectrum'] = None

    return obs
Ejemplo n.º 6
0
    def test_docs_example(self):
        import numpy as np

        from hyperion.model import ModelOutput
        from hyperion.util.constants import pc

        from fluxcompensator.cube import *
        from fluxcompensator.psf import *
        from fluxcompensator.utils.resolution import *

        # read in from HYPERION
        m = ModelOutput(
            os.path.join(os.path.dirname(__file__), 'hyperion_output.rtout'))
        array = m.get_image(group=0,
                            inclination=0,
                            distance=300 * pc,
                            units='ergs/cm^2/s')

        # initial FluxCompensator array
        c = SyntheticCube(input_array=array,
                          unit_out='ergs/cm^2/s',
                          name='test_cube')

        # dered with provided extinction law
        ext = c.extinction(A_v=20.)

        # change resolution to 10-times of the initial
        zoom = ext.change_resolution(new_resolution=10 *
                                     ext.resolution['arcsec'],
                                     grid_plot=True)

        import fluxcompensator.database.missions as PSFs

        # call object from the psf database
        psf_object = getattr(PSFs, 'PACS1_PSF')

        # convolve with PSF
        psf = zoom.convolve_psf(psf_object)

        import fluxcompensator.database.missions as filters

        # call object from the filter database
        filter_input = getattr(filters, 'PACS1_FILTER')

        # convolve with filter
        filtered = psf.convolve_filter(filter_input,
                                       plot_rebin=None,
                                       plot_rebin_dpi=None)

        # add noise
        noise = filtered.add_noise(mu_noise=0,
                                   sigma_noise=5e-15,
                                   diagnostics=None)
Ejemplo n.º 7
0
    def __init__(self,
                 rtout,
                 velfile,
                 cs,
                 age,
                 omega,
                 rmin=0,
                 mmw=2.37,
                 g2d=100,
                 truncate=None,
                 debug=False,
                 load_full=True,
                 fix_tsc=True,
                 hybrid_tsc=False,
                 interpolate=False,
                 TSC_dir='',
                 tsc_outdir=''):
        self.rtout = rtout
        self.velfile = velfile
        if load_full:
            self.hyperion = ModelOutput(rtout)
            self.hy_grid = self.hyperion.get_quantities()
        self.rmin = rmin * 1e2  # rmin defined in LIME, which use SI unit
        self.mmw = mmw
        self.g2d = g2d
        self.cs = cs  # in km/s
        self.age = age  # in year
        # YLY update - add omega
        self.omega = omega
        self.r_inf = self.cs * 1e5 * self.age * yr  # in cm

        # option to truncate the sphere to be a cylinder
        # the value is given in au to specify the radius of the truncated cylinder viewed from the observer
        self.truncate = truncate

        # debug option: print out every call to getDensity, getVelocity and getAbundance
        self.debug = debug

        # option to use simple Trapezoid rule average for getting density, temperature, and velocity
        self.interpolate = interpolate

        self.tsc2d = getTSC(age,
                            cs,
                            omega,
                            velfile=velfile,
                            TSC_dir=TSC_dir,
                            outdir=tsc_outdir,
                            outname='tsc_regrid')
Ejemplo n.º 8
0
    def load_data(self,
                  key,
                  file_name=None,
                  source=None,
                  incl=None,
                  angle=None,
                  dtype=None):
        """Load data for key.

        Parameters:
            key: data to load.
            filename: file to open.
            source: source object.
            incl: inclination index.
            angle: inclination angle (model config must be pre-loaded)
            dtype: data type.
        """

        if key == 'model':
            assert os.path.isfile(file_name)
            self.data[key] = ModelOutput(file_name)
        elif file_name and dtype:
            assert os.path.isfile(file_name)
            self.data[key] = load_data_by_type(file_name, dtype.lower(),
                                               REGISTERED_CLASSES)
        elif key == 'sed':
            assert incl is not None or (angle is not None and \
                    self.config is not None)
            wlg, F = self.data['model'].get_sed(
                group=0,
                distance=source.distance.cgs.value,
                inclination=incl,
                units='Jy')
            data = np.array(zip(wlg, F[0]),
                            dtype=[('wlg', float), ('F', float)])
            self.data[key] = SED(data=data,
                                 units={
                                     'wlg': 1. * u.micron,
                                     'F': 1. * u.Jy
                                 })
        else:
            raise NotImplementedError
Ejemplo n.º 9
0
    def setup_method(self, method):

        import numpy as np

        from hyperion.model import ModelOutput
        from hyperion.util.constants import kpc
        from fluxcompensator.cube import *

        # read in from HYPERION
        m = ModelOutput(
            os.path.join(os.path.dirname(__file__), 'hyperion_output.rtout'))
        array = m.get_image(group=0,
                            inclination=0,
                            distance=10 * kpc,
                            units='ergs/cm^2/s')

        # initial FluxCompensator array
        self.FC_object = SyntheticCube(input_array=array,
                                       unit_out='ergs/cm^2/s',
                                       name='test_cube')
Ejemplo n.º 10
0
    def test_docs_sed(self):

        import numpy as np

        from hyperion.model import ModelOutput
        from hyperion.util.constants import pc
        from fluxcompensator.sed import *

        # read in from HYPERION
        m = ModelOutput(
            os.path.join(os.path.dirname(__file__), 'B5_class2_45.rtout'))
        array = m.get_sed(group=0,
                          inclination=0,
                          distance=300 * pc,
                          units='ergs/cm^2/s')

        # initial FluxCompensator array
        s = SyntheticSED(input_array=array,
                         unit_out='ergs/cm^2/s',
                         name='test_sed')
Ejemplo n.º 11
0
def getRadialDensity(rtout, angle, plotdir):
    """
    """
    import numpy as np
    from hyperion.model import ModelOutput


    m = ModelOutput(rtout)
    q = m.get_quantities()
    r_wall = q.r_wall; theta_wall = q.t_wall; phi_wall = q.p_wall
    # get the cell coordinates
    rc = r_wall[0:len(r_wall)-1] + 0.5*(r_wall[1:len(r_wall)]-r_wall[0:len(r_wall)-1])
    thetac = theta_wall[0:len(theta_wall)-1] + \
             0.5*(theta_wall[1:len(theta_wall)]-theta_wall[0:len(theta_wall)-1])
    phic = phi_wall[0:len(phi_wall)-1] + \
           0.5*(phi_wall[1:len(phi_wall)]-phi_wall[0:len(phi_wall)-1])
    #
    rho = q['density'].array[0]

    # find the closest angle in the thetac grid
    ind = np.argsort(abs(thetac-angle*np.pi/180.))[0]

    return rc, rho[0,ind,:]
Ejemplo n.º 12
0
def extract_hyperion(filename,indir=None,outdir=None,dstar=178.0,wl_aper=None,save=True,filter_func=False,\
    plot_all=False,clean=False,exclude_wl=[],log=True):
    def l_bol(wl, fv, dist=178.0):
        import numpy as np
        import astropy.constants as const
        # wavelength unit: um
        # Flux density unit: Jy
        #
        # constants setup
        #
        c = const.c.cgs.value
        pc = const.pc.cgs.value
        PI = np.pi
        SL = const.L_sun.cgs.value
        # Convert the unit from Jy to erg s-1 cm-2 Hz-1
        fv = np.array(fv) * 1e-23
        freq = c / (1e-4 * np.array(wl))

        diff_dum = freq[1:] - freq[0:-1]
        freq_interpol = np.hstack(
            (freq[0:-1] + diff_dum / 2.0, freq[0:-1] + diff_dum / 2.0, freq[0],
             freq[-1]))
        freq_interpol = freq_interpol[np.argsort(freq_interpol)[::-1]]
        fv_interpol = np.empty(len(freq_interpol))
        # calculate the histogram style of spectrum
        #
        for i in range(0, len(fv)):
            if i == 0:
                fv_interpol[i] = fv[i]
            else:
                fv_interpol[2 * i - 1] = fv[i - 1]
                fv_interpol[2 * i] = fv[i]
        fv_interpol[-1] = fv[-1]

        dv = freq_interpol[0:-1] - freq_interpol[1:]
        dv = np.delete(dv, np.where(dv == 0))

        fv = fv[np.argsort(freq)]
        freq = freq[np.argsort(freq)]

        return (np.trapz(fv, freq) * 4. * PI * (dist * pc)**2) / SL

    # to avoid X server error
    import matplotlib as mpl
    mpl.use('Agg')
    #
    import matplotlib.pyplot as plt
    import numpy as np
    import os
    from hyperion.model import ModelOutput, Model
    from scipy.interpolate import interp1d
    from hyperion.util.constants import pc, c, lsun, au
    from astropy.io import ascii
    import sys
    sys.path.append(os.path.expanduser('~') + '/programs/spectra_analysis/')
    from phot_filter import phot_filter
    from get_bhr71_obs import get_bhr71_obs

    # seaborn colormap, because jet is bad obviously
    import seaborn.apionly as sns

    # Read in the observation data and calculate the noise & variance
    if indir == None:
        indir = '/Users/yaolun/bhr71/'
    if outdir == None:
        outdir = '/Users/yaolun/bhr71/hyperion/'

    # assign the file name from the input file
    print_name = os.path.splitext(os.path.basename(filename))[0]

    # use a canned function to extract BHR71 observational data
    bhr71 = get_bhr71_obs(indir)  # unit in um, Jy
    wl_tot, flux_tot, unc_tot = bhr71['spec']
    flux_tot = flux_tot * 1e-23  # convert unit from Jy to erg s-1 cm-2 Hz-1
    unc_tot = unc_tot * 1e-23
    l_bol_obs = l_bol(wl_tot, flux_tot * 1e23)

    wl_phot, flux_phot, flux_sig_phot = bhr71['phot']
    flux_phot = flux_phot * 1e-23  # convert unit from Jy to erg s-1 cm-2 Hz-1
    flux_sig_phot = flux_sig_phot * 1e-23
    # Print the observed L_bol
    # wl_tot = np.hstack((wl_irs,wl_obs,wl_phot))
    # flux_tot = np.hstack((flux_irs,flux_obs,flux_phot))
    # flux_tot = flux_tot[np.argsort(wl_tot)]
    # wl_tot = wl_tot[np.argsort(wl_tot)]
    # l_bol_obs = l_bol(wl_tot,flux_tot*1e23)

    # Open the model
    m = ModelOutput(filename)

    if wl_aper == None:
        wl_aper = [
            3.6, 4.5, 5.8, 8.0, 10, 16, 20, 24, 35, 70, 100, 160, 250, 350,
            500, 850
        ]

    # Create the plot
    mag = 1.5
    fig = plt.figure(figsize=(8 * mag, 6 * mag))
    ax_sed = fig.add_subplot(1, 1, 1)

    # Plot the observed SED
    # plot the observed spectra
    if not clean:
        color_seq = ['Green', 'Red', 'Blue']
    else:
        color_seq = ['DimGray', 'DimGray', 'DimGray']
    # plot the observations
    if log:
        pacs, = ax_sed.plot(np.log10(wl_tot[(wl_tot>40) & (wl_tot<190.31)]),\
                            np.log10(c/(wl_tot[(wl_tot>40) & (wl_tot<190.31)]*1e-4)*flux_tot[(wl_tot>40) & (wl_tot<190.31)]),\
                            '-',color=color_seq[0],linewidth=1.5*mag, alpha=0.7)
        spire, = ax_sed.plot(np.log10(wl_tot[wl_tot > 194]),np.log10(c/(wl_tot[wl_tot > 194]*1e-4)*flux_tot[wl_tot > 194]),\
                            '-',color=color_seq[1],linewidth=1.5*mag, alpha=0.7)
        irs, = ax_sed.plot(np.log10(wl_tot[wl_tot < 40]),np.log10(c/(wl_tot[wl_tot < 40]*1e-4)*flux_tot[wl_tot < 40]),\
                            '-',color=color_seq[2],linewidth=1.5*mag, alpha=0.7)
        photometry, = ax_sed.plot(np.log10(wl_phot),
                                  np.log10(c / (wl_phot * 1e-4) * flux_phot),
                                  's',
                                  mfc='DimGray',
                                  mec='k',
                                  markersize=8)
        # plot the observed photometry data
        ax_sed.errorbar(np.log10(wl_phot),np.log10(c/(wl_phot*1e-4)*flux_phot),\
            yerr=[np.log10(c/(wl_phot*1e-4)*flux_phot)-np.log10(c/(wl_phot*1e-4)*(flux_phot-flux_sig_phot)),\
                  np.log10(c/(wl_phot*1e-4)*(flux_phot+flux_sig_phot))-np.log10(c/(wl_phot*1e-4)*flux_phot)],\
            fmt='s',mfc='DimGray',mec='k',markersize=8)
    else:
        pacs, = ax_sed.plot(np.log10(wl_tot[(wl_tot>40) & (wl_tot<190.31)]),\
                            c/(wl_tot[(wl_tot>40) & (wl_tot<190.31)]*1e-4)*flux_tot[(wl_tot>40) & (wl_tot<190.31)],\
                            '-',color=color_seq[0],linewidth=1.5*mag, alpha=0.7)
        spire, = ax_sed.plot(np.log10(wl_tot[wl_tot > 194]),c/(wl_tot[wl_tot > 194]*1e-4)*flux_tot[wl_tot > 194],\
                            '-',color=color_seq[1],linewidth=1.5*mag, alpha=0.7)
        irs, = ax_sed.plot(np.log10(wl_tot[wl_tot < 40]),c/(wl_tot[wl_tot < 40]*1e-4)*flux_tot[wl_tot < 40],\
                            '-',color=color_seq[2],linewidth=1.5*mag, alpha=0.7)
        photometry, = ax_sed.plot(wl_phot,
                                  c / (wl_phot * 1e-4) * flux_phot,
                                  's',
                                  mfc='DimGray',
                                  mec='k',
                                  markersize=8)
        # plot the observed photometry data
        ax_sed.errorbar(np.log10(wl_phot),c/(wl_phot*1e-4)*flux_phot,\
            yerr=[c/(wl_phot*1e-4)*flux_phot-c/(wl_phot*1e-4)*(flux_phot-flux_sig_phot),\
                  c/(wl_phot*1e-4)*(flux_phot+flux_sig_phot)-c/(wl_phot*1e-4)*flux_phot],\
            fmt='s',mfc='DimGray',mec='k',markersize=8)

    if not clean:
        ax_sed.text(0.75,
                    0.9,
                    r'$\rm{L_{bol}= %5.2f L_{\odot}}$' % l_bol_obs,
                    fontsize=mag * 16,
                    transform=ax_sed.transAxes)
    # else:
    #     pacs, = ax_sed.plot(np.log10(wl_tot[(wl_tot>40) & (wl_tot<190.31)]),\
    #                         np.log10(c/(wl_tot[(wl_tot>40) & (wl_tot<190.31)]*1e-4)*flux_tot[(wl_tot>40) & (wl_tot<190.31)]),\
    #                         '-',color='DimGray',linewidth=1.5*mag, alpha=0.7)
    #     spire, = ax_sed.plot(np.log10(wl_tot[wl_tot > 194]),np.log10(c/(wl_tot[wl_tot > 194]*1e-4)*flux_tot[wl_tot > 194]),\
    #                         '-',color='DimGray',linewidth=1.5*mag, alpha=0.7)
    #     irs, = ax_sed.plot(np.log10(wl_tot[wl_tot < 40]),np.log10(c/(wl_tot[wl_tot < 40]*1e-4)*flux_tot[wl_tot < 40]),\
    #                         '-',color='DimGray',linewidth=1.5*mag, alpha=0.7)

    # Extract the SED for the smallest inclination and largest aperture, and
    # scale to 300pc. In Python, negative indices can be used for lists and
    # arrays, and indicate the position from the end. So to get the SED in the
    # largest aperture, we set aperture=-1.
    # aperture group is aranged from smallest to infinite
    sed_inf = m.get_sed(group=0,
                        inclination=0,
                        aperture=-1,
                        distance=dstar * pc,
                        uncertainties=True)

    # plot the simulated SED
    if clean == False:
        sim, = ax_sed.plot(np.log10(sed_inf.wav),
                           np.log10(sed_inf.val),
                           '-',
                           color='GoldenRod',
                           linewidth=0.5 * mag)
        ax_sed.fill_between(np.log10(sed_inf.wav), np.log10(sed_inf.val-sed_inf.unc), np.log10(sed_inf.val+sed_inf.unc),\
            color='GoldenRod', alpha=0.5)
    # get flux at different apertures
    flux_aper = np.zeros_like(wl_aper, dtype=float)
    unc_aper = np.zeros_like(wl_aper, dtype=float)
    a = np.zeros_like(wl_aper) + 1
    color_list = plt.cm.jet(np.linspace(0, 1, len(wl_aper) + 1))
    for i in range(0, len(wl_aper)):
        if wl_aper[i] in exclude_wl:
            continue
        # if (wl_aper[i] == 5.8) or (wl_aper[i] == 8.0) or (wl_aper[i] == 10.5) or (wl_aper[i] == 11):
        #     continue
        sed_dum = m.get_sed(group=i + 1,
                            inclination=0,
                            aperture=-1,
                            distance=dstar * pc,
                            uncertainties=True)
        if plot_all == True:
            ax_sed.plot(np.log10(sed_dum.wav),
                        np.log10(sed_dum.val),
                        '-',
                        color=color_list[i])
            ax_sed.fill_between(np.log10(sed_dum.wav), np.log10(sed_dum.val-sed_dum.unc), np.log10(sed_dum.val+sed_dum.unc),\
                color=color_list[i], alpha=0.5)
        if filter_func == False:
            # use a rectangle function the average the simulated SED
            # apply the spectral resolution
            if (wl_aper[i] < 50.) & (wl_aper[i] >= 5):
                res = 60.
            elif wl_aper[i] < 5:
                res = 10.
            else:
                res = 1000.
            ind = np.where((sed_dum.wav < wl_aper[i] * (1 + 1. / res))
                           & (sed_dum.wav > wl_aper[i] * (1 - 1. / res)))
            if len(ind[0]) != 0:
                flux_aper[i] = np.mean(sed_dum.val[ind])
                unc_aper[i] = np.mean(sed_dum.unc[ind])
            else:
                f = interp1d(sed_dum.wav, sed_dum.val)
                f_unc = interp1d(sed_dum.wav, sed_dum.unc)
                flux_aper[i] = f(wl_aper[i])
                unc_aper[i] = f_unc(wl_aper[i])
        else:
            # apply the filter function
            # decide the filter name
            if wl_aper[i] == 70:
                fil_name = 'Herschel PACS 70um'
            elif wl_aper[i] == 100:
                fil_name = 'Herschel PACS 100um'
            elif wl_aper[i] == 160:
                fil_name = 'Herschel PACS 160um'
            elif wl_aper[i] == 250:
                fil_name = 'Herschel SPIRE 250um'
            elif wl_aper[i] == 350:
                fil_name = 'Herschel SPIRE 350um'
            elif wl_aper[i] == 500:
                fil_name = 'Herschel SPIRE 500um'
            elif wl_aper[i] == 3.6:
                fil_name = 'IRAC Channel 1'
            elif wl_aper[i] == 4.5:
                fil_name = 'IRAC Channel 2'
            elif wl_aper[i] == 5.8:
                fil_name = 'IRAC Channel 3'
            elif wl_aper[i] == 8.0:
                fil_name = 'IRAC Channel 4'
            elif wl_aper[i] == 24:
                fil_name = 'MIPS 24um'
            elif wl_aper[i] == 850:
                fil_name = 'SCUBA 850WB'
            else:
                fil_name = None

            if fil_name != None:
                filter_func = phot_filter(fil_name)
                # Simulated SED should have enough wavelength coverage for applying photometry filters.
                f = interp1d(sed_dum.wav, sed_dum.val)
                f_unc = interp1d(sed_dum.wav, sed_dum.unc)
                flux_aper[i] = np.trapz(
                    filter_func['wave'] / 1e4,
                    f(filter_func['wave'] / 1e4) *
                    filter_func['transmission']) / np.trapz(
                        filter_func['wave'] / 1e4, filter_func['transmission'])
                unc_aper[i] = abs(
                    np.trapz((filter_func['wave'] / 1e4)**2,
                             (f_unc(filter_func['wave'] / 1e4) *
                              filter_func['transmission'])**2))**0.5 / abs(
                                  np.trapz(filter_func['wave'] / 1e4,
                                           filter_func['transmission']))
            else:
                # use a rectangle function the average the simulated SED
                # apply the spectral resolution
                if (wl_aper[i] < 50.) & (wl_aper[i] >= 5):
                    res = 60.
                elif wl_aper[i] < 5:
                    res = 10.
                else:
                    res = 1000.
                ind = np.where((sed_dum.wav < wl_aper[i] * (1 + 1. / res))
                               & (sed_dum.wav > wl_aper[i] * (1 - 1. / res)))
                if len(ind[0]) != 0:
                    flux_aper[i] = np.mean(sed_dum.val[ind])
                    unc_aper[i] = np.mean(sed_dum.unc[ind])
                else:
                    f = interp1d(sed_dum.wav, sed_dum.val)
                    f_unc = interp1d(sed_dum.wav, sed_dum.unc)
                    flux_aper[i] = f(wl_aper[i])
                    unc_aper[i] = f_unc(wl_aper[i])
    # temperory step: solve issue of uncertainty greater than the value
    for i in range(len(wl_aper)):
        if unc_aper[i] >= flux_aper[i]:
            unc_aper[i] = flux_aper[i] - 1e-20

    # perform the same procedure of flux extraction of aperture flux with observed spectra
    wl_aper = np.array(wl_aper, dtype=float)
    obs_aper_wl = wl_aper[(wl_aper >= min(wl_tot)) & (wl_aper <= max(wl_tot))]
    obs_aper_sed = np.zeros_like(obs_aper_wl)
    obs_aper_sed_unc = np.zeros_like(obs_aper_wl)
    sed_tot = c / (wl_tot * 1e-4) * flux_tot
    sed_unc_tot = c / (wl_tot * 1e-4) * unc_tot
    # wl_tot and flux_tot are already hstacked and sorted by wavelength
    for i in range(0, len(obs_aper_wl)):
        if obs_aper_wl[i] in exclude_wl:
            continue
        if filter_func == False:
            # use a rectangle function the average the simulated SED
            # apply the spectral resolution
            if (obs_aper_wl[i] < 50.) & (obs_aper_wl[i] >= 5):
                res = 60.
            elif obs_aper_wl[i] < 5:
                res = 10.
            else:
                res = 1000.
            ind = np.where((wl_tot < obs_aper_wl[i] * (1 + 1. / res))
                           & (wl_tot > obs_aper_wl[i] * (1 - 1. / res)))
            if len(ind[0]) != 0:
                obs_aper_sed[i] = np.mean(sed_tot[ind])
                obs_aper_sed_unc[i] = np.mean(sed_unc_tot[ind])
            else:
                f = interp1d(wl_tot, sed_tot)
                f_unc = interp1d(wl_tot, sed_unc_tot)
                obs_aper_sed[i] = f(obs_aper_wl[i])
                obs_aper_sed_unc[i] = f_unc(obs_aper_wl[i])
        else:
            # apply the filter function
            # decide the filter name
            if obs_aper_wl[i] == 70:
                fil_name = 'Herschel PACS 70um'
            elif obs_aper_wl[i] == 100:
                fil_name = 'Herschel PACS 100um'
            elif obs_aper_wl[i] == 160:
                fil_name = 'Herschel PACS 160um'
            elif obs_aper_wl[i] == 250:
                fil_name = 'Herschel SPIRE 250um'
            elif obs_aper_wl[i] == 350:
                fil_name = 'Herschel SPIRE 350um'
            elif obs_aper_wl[i] == 500:
                fil_name = 'Herschel SPIRE 500um'
            elif obs_aper_wl[i] == 3.6:
                fil_name = 'IRAC Channel 1'
            elif obs_aper_wl[i] == 4.5:
                fil_name = 'IRAC Channel 2'
            elif obs_aper_wl[i] == 5.8:
                fil_name = 'IRAC Channel 3'
            elif obs_aper_wl[i] == 8.0:
                fil_name = 'IRAC Channel 4'
            elif obs_aper_wl[i] == 24:
                fil_name = 'MIPS 24um'
            # elif obs_aper_wl[i] == 850:
            #     fil_name = 'SCUBA 850WB'
            # do not have SCUBA spectra
            else:
                fil_name = None

            # print obs_aper_wl[i], fil_name

            if fil_name != None:
                filter_func = phot_filter(fil_name)
                # Observed SED needs to be trimmed before applying photometry filters
                filter_func = filter_func[(filter_func['wave']/1e4 >= min(wl_tot))*\
                                          ((filter_func['wave']/1e4 >= 54.8)+(filter_func['wave']/1e4 <= 36.0853))*\
                                          ((filter_func['wave']/1e4 <= 95.05)+(filter_func['wave']/1e4 >=103))*\
                                          ((filter_func['wave']/1e4 <= 190.31)+(filter_func['wave']/1e4 >= 195))*\
                                          (filter_func['wave']/1e4 <= max(wl_tot))]
                f = interp1d(wl_tot, sed_tot)
                f_unc = interp1d(wl_tot, sed_unc_tot)
                obs_aper_sed[i] = np.trapz(
                    filter_func['wave'] / 1e4,
                    f(filter_func['wave'] / 1e4) *
                    filter_func['transmission']) / np.trapz(
                        filter_func['wave'] / 1e4, filter_func['transmission'])
                obs_aper_sed_unc[i] = abs(
                    np.trapz((filter_func['wave'] / 1e4)**2,
                             (f_unc(filter_func['wave'] / 1e4) *
                              filter_func['transmission'])**2))**0.5 / abs(
                                  np.trapz(filter_func['wave'] / 1e4,
                                           filter_func['transmission']))
            else:
                # use a rectangle function the average the simulated SED
                # apply the spectral resolution
                if (obs_aper_wl[i] < 50.) & (obs_aper_wl[i] >= 5):
                    res = 60.
                elif obs_aper_wl[i] < 5:
                    res = 10.
                else:
                    res = 1000.
                ind = np.where((wl_tot < obs_aper_wl[i] * (1 + 1. / res))
                               & (wl_tot > obs_aper_wl[i] * (1 - 1. / res)))
                if len(ind[0]) != 0:
                    obs_aper_sed[i] = np.mean(sed_tot[ind])
                    obs_aper_sed_unc[i] = np.mean(sed_unc_tot[ind])
                else:
                    f = interp1d(wl_tot, sed_tot)
                    f_unc = interp1d(wl_tot, sed_unc_tot)
                    obs_aper_sed[i] = f(obs_aper_wl[i])
                    obs_aper_sed_unc[i] = f_unc(obs_aper_wl[i])

    # if clean == False:
    #     if log:
    #         aper_obs = ax_sed.errorbar(np.log10(obs_aper_wl), np.log10(obs_aper_sed), \
    #             yerr=[np.log10(obs_aper_sed)-np.log10(obs_aper_sed-obs_aper_sed_unc), np.log10(obs_aper_sed+obs_aper_sed_unc)-np.log10(obs_aper_sed)],\
    #             fmt='s', mec='Magenta', mfc='Magenta', markersize=10, elinewidth=3, ecolor='Magenta',capthick=3,barsabove=True)
    #         aper = ax_sed.errorbar(np.log10(wl_aper), np.log10(flux_aper),\
    #             yerr=[np.log10(flux_aper)-np.log10(flux_aper-unc_aper), np.log10(flux_aper+unc_aper)-np.log10(flux_aper)],\
    #             fmt='o', mfc='None', mec='k', ecolor='Black', markersize=12, markeredgewidth=3, elinewidth=3, barsabove=True)
    #     else:
    #         aper_obs = ax_sed.errorbar(obs_aper_wl, obs_aper_sed, yerr=obs_aper_sed_unc,\
    #             fmt='s', mec='Magenta', mfc='Magenta', markersize=10, elinewidth=3, ecolor='Magenta',capthick=3,barsabove=True)
    #         aper = ax_sed.errorbar(wl_aper, flux_aper, yerr=unc_aper,\
    #             fmt='o', mfc='None', mec='k', ecolor='Black', markersize=12, markeredgewidth=3, elinewidth=3, barsabove=True)
    # else:
    if log:
        aper_obs = ax_sed.errorbar(np.log10(obs_aper_wl), np.log10(obs_aper_sed),\
            yerr=[np.log10(obs_aper_sed)-np.log10(obs_aper_sed-obs_aper_sed_unc), np.log10(obs_aper_sed+obs_aper_sed_unc)-np.log10(obs_aper_sed)],\
            fmt='s', mec='None', mfc='r', markersize=10, linewidth=1.5, ecolor='Red', elinewidth=3, capthick=3, barsabove=True)
        aper = ax_sed.errorbar(np.log10(wl_aper),np.log10(flux_aper),\
            yerr=[np.log10(flux_aper)-np.log10(flux_aper-unc_aper), np.log10(flux_aper+unc_aper)-np.log10(flux_aper)],\
            fmt='o', mec='Blue', mfc='None', color='b',markersize=12, markeredgewidth=2.5, linewidth=1.7, ecolor='Blue', elinewidth=3, barsabove=True)
        ax_sed.set_ylim([-14, -7])
        ax_sed.set_xlim([0, 3])
    else:
        aper_obs = ax_sed.errorbar(np.log10(obs_aper_wl), obs_aper_sed, yerr=obs_aper_sed_unc,\
            fmt='s', mec='None', mfc='r', markersize=10, linewidth=1.5, ecolor='Red', elinewidth=3, capthick=3, barsabove=True)
        aper = ax_sed.errorbar(np.log10(wl_aper),flux_aper, yerr=unc_aper,\
            fmt='o', mec='Blue', mfc='None', color='b',markersize=12, markeredgewidth=2.5, linewidth=1.7, ecolor='Blue', elinewidth=3, barsabove=True)
        # ax_sed.set_xlim([1, 1000])
        ax_sed.set_xlim([0, 3])
        # ax_sed.set_ylim([1e-14, 1e-8])
    # calculate the bolometric luminosity of the aperture
    # print flux_aper
    l_bol_sim = l_bol(wl_aper,
                      flux_aper / (c / np.array(wl_aper) * 1e4) * 1e23)
    print 'Bolometric luminosity of simulated spectrum: %5.2f lsun' % l_bol_sim

    # print out the sed into ascii file for reading in later
    if save == True:
        # unapertured SED
        foo = open(outdir + print_name + '_sed_inf.txt', 'w')
        foo.write('%12s \t %12s \t %12s \n' % ('wave', 'vSv', 'sigma_vSv'))
        for i in range(0, len(sed_inf.wav)):
            foo.write('%12g \t %12g \t %12g \n' %
                      (sed_inf.wav[i], sed_inf.val[i], sed_inf.unc[i]))
        foo.close()
        # SED with convolution of aperture sizes
        foo = open(outdir + print_name + '_sed_w_aperture.txt', 'w')
        foo.write('%12s \t %12s \t %12s \n' % ('wave', 'vSv', 'sigma_vSv'))
        for i in range(0, len(wl_aper)):
            foo.write('%12g \t %12g \t %12g \n' %
                      (wl_aper[i], flux_aper[i], unc_aper[i]))
        foo.close()

    # Read in and plot the simulated SED produced by RADMC-3D using the same parameters
    # [wl,fit] = np.genfromtxt(indir+'hyperion/radmc_comparison/spectrum.out',dtype='float',skip_header=3).T
    # l_bol_radmc = l_bol(wl,fit*1e23/dstar**2)
    # radmc, = ax_sed.plot(np.log10(wl),np.log10(c/(wl*1e-4)*fit/dstar**2),'-',color='DimGray', linewidth=1.5*mag, alpha=0.5)

    # print the L bol of the simulated SED (both Hyperion and RADMC-3D)
    # lg_sim = ax_sed.legend([sim,radmc],[r'$\rm{L_{bol,sim}=%5.2f\,L_{\odot},\,L_{center}=9.18\,L_{\odot}}$' % l_bol_sim, \
    #   r'$\rm{L_{bol,radmc3d}=%5.2f\,L_{\odot},\,L_{center}=9.18\,L_{\odot}}$' % l_bol_radmc],\
    #   loc='lower right',fontsize=mag*16)

    # read the input central luminosity by reading in the source information from output file
    dum = Model()
    dum.use_sources(filename)
    L_cen = dum.sources[0].luminosity / lsun

    # legend
    lg_data = ax_sed.legend([irs, photometry, aper, aper_obs],\
    [r'$\rm{observation}$',\
    r'$\rm{photometry}$',r'$\rm{F_{aper,sim}}$',r'$\rm{F_{aper,obs}}$'],\
    loc='upper left',fontsize=14*mag,numpoints=1,framealpha=0.3)
    if clean == False:
        lg_sim = ax_sed.legend([sim],[r'$\rm{L_{bol,sim}=%5.2f\,L_{\odot},\,L_{center}=%5.2f\,L_{\odot}}$' % (l_bol_sim, L_cen)], \
            loc='lower right',fontsize=mag*16)
        plt.gca().add_artist(lg_data)

    # plot setting
    ax_sed.set_xlabel(r'$\rm{log\,\lambda\,({\mu}m)}$', fontsize=mag * 20)
    ax_sed.set_ylabel(r'$\rm{log\,\nu S_{\nu}\,(erg/cm^{2}/s)}$',
                      fontsize=mag * 20)
    [
        ax_sed.spines[axis].set_linewidth(1.5 * mag)
        for axis in ['top', 'bottom', 'left', 'right']
    ]
    ax_sed.minorticks_on()
    ax_sed.tick_params('both',
                       labelsize=mag * 18,
                       width=1.5 * mag,
                       which='major',
                       pad=15,
                       length=5 * mag)
    ax_sed.tick_params('both',
                       labelsize=mag * 18,
                       width=1.5 * mag,
                       which='minor',
                       pad=15,
                       length=2.5 * mag)

    # fix the tick label font
    ticks_font = mpl.font_manager.FontProperties(family='STIXGeneral',
                                                 size=mag * 18)
    for label in ax_sed.get_xticklabels():
        label.set_fontproperties(ticks_font)
    for label in ax_sed.get_yticklabels():
        label.set_fontproperties(ticks_font)

    # if clean == False:
    #     lg_data = ax_sed.legend([irs, pacs, spire,photometry],[r'$\rm{{\it Spitzer}-IRS}$',r'$\rm{{\it Herschel}-PACS}$',r'$\rm{{\it Herschel}-SPIRE}$',r'$\rm{Photometry}$'],\
    #                             loc='upper left',fontsize=14*mag,numpoints=1,framealpha=0.3)
    #     plt.gca().add_artist(lg_sim)
    # else:
    #     lg_data = ax_sed.legend([irs, photometry, aper, aper_obs],\
    #     [r'$\rm{observation}$',\
    #     r'$\rm{photometry}$',r'$\rm{F_{aper,sim}}$',r'$\rm{F_{aper,obs}}$'],\
    #     loc='upper left',fontsize=14*mag,numpoints=1,framealpha=0.3)

    # Write out the plot
    fig.savefig(outdir + print_name + '_sed.pdf',
                format='pdf',
                dpi=300,
                bbox_inches='tight')
    fig.clf()

    # Package for matching the colorbar
    from mpl_toolkits.axes_grid1 import make_axes_locatable

    # Extract the image for the first inclination, and scale to 300pc. We
    # have to specify group=1 as there is no image in group 0.
    image = m.get_image(group=len(wl_aper) + 1,
                        inclination=0,
                        distance=dstar * pc,
                        units='MJy/sr')
    # image = m.get_image(group=14, inclination=0, distance=dstar * pc, units='MJy/sr')
    # Open figure and create axes
    # fig = plt.figure(figsize=(8, 8))
    fig, axarr = plt.subplots(3,
                              3,
                              sharex='col',
                              sharey='row',
                              figsize=(13.5, 12))

    # Pre-set maximum for colorscales
    VMAX = {}
    # VMAX[3.6] = 10.
    # VMAX[24] = 100.
    # VMAX[160] = 2000.
    # VMAX[500] = 2000.
    VMAX[100] = 10.
    VMAX[250] = 100.
    VMAX[500] = 2000.
    VMAX[1000] = 2000.

    # We will now show four sub-plots, each one for a different wavelength
    # for i, wav in enumerate([3.6, 24, 160, 500]):
    # for i, wav in enumerate([100, 250, 500, 1000]):
    # for i, wav in enumerate([4.5, 9.7, 24, 40, 70, 100, 250, 500, 1000]):
    for i, wav in enumerate([3.6, 8.0, 9.7, 24, 40, 100, 250, 500, 1000]):

        # ax = fig.add_subplot(3, 3, i + 1)
        ax = axarr[i / 3, i % 3]

        # Find the closest wavelength
        iwav = np.argmin(np.abs(wav - image.wav))

        # Calculate the image width in arcseconds given the distance used above
        # get the max radius
        rmax = max(m.get_quantities().r_wall)
        w = np.degrees(rmax / image.distance) * 3600.

        # Image in the unit of MJy/sr
        # Change it into erg/s/cm2/Hz/sr
        factor = 1e-23 * 1e6
        # avoid zero in log
        # flip the image, because the setup of inclination is upside down
        val = image.val[::-1, :, iwav] * factor + 1e-30
        # val = image.val[:, :, iwav] * factor + 1e-30

        # This is the command to show the image. The parameters vmin and vmax are
        # the min and max levels for the colorscale (remove for default values).
        # cmap = sns.cubehelix_palette(start=0.1, rot=-0.7, gamma=0.2, as_cmap=True)
        cmap = plt.cm.CMRmap
        im = ax.imshow(np.log10(val),
                       vmin=-22,
                       vmax=-12,
                       cmap=cmap,
                       origin='lower',
                       extent=[-w, w, -w, w],
                       aspect=1)

        # fix the tick label font
        ticks_font = mpl.font_manager.FontProperties(family='STIXGeneral',
                                                     size=14)
        for label in ax.get_xticklabels():
            label.set_fontproperties(ticks_font)
        for label in ax.get_yticklabels():
            label.set_fontproperties(ticks_font)

        # Colorbar setting
        # create an axes on the right side of ax. The width of cax will be 5%
        # of ax and the padding between cax and ax will be fixed at 0.05 inch.
        if (i + 1) % 3 == 0:
            divider = make_axes_locatable(ax)
            cax = divider.append_axes("right", size="5%", pad=0.05)
            cb = fig.colorbar(im, cax=cax)
            cb.solids.set_edgecolor("face")
            cb.ax.minorticks_on()
            cb.ax.set_ylabel(
                r'$\rm{log(I_{\nu})\,[erg\,s^{-1}\,cm^{-2}\,Hz^{-1}\,sr^{-1}]}$',
                fontsize=12)
            cb_obj = plt.getp(cb.ax.axes, 'yticklabels')
            plt.setp(cb_obj, fontsize=12)
            # fix the tick label font
            ticks_font = mpl.font_manager.FontProperties(family='STIXGeneral',
                                                         size=12)
            for label in cb.ax.get_yticklabels():
                label.set_fontproperties(ticks_font)

        if (i + 1) == 7:
            # Finalize the plot
            ax.set_xlabel(r'$\rm{RA\,Offset\,(arcsec)}$', fontsize=14)
            ax.set_ylabel(r'$\rm{Dec\,Offset\,(arcsec)}$', fontsize=14)

        ax.tick_params(axis='both', which='major', labelsize=16)
        ax.set_adjustable('box-forced')
        ax.text(0.7,
                0.88,
                str(wav) + r'$\rm{\,\mu m}$',
                fontsize=16,
                color='white',
                transform=ax.transAxes)

    fig.subplots_adjust(hspace=0, wspace=-0.2)

    # Adjust the spaces between the subplots
    # plt.tight_layout()
    fig.savefig(outdir + print_name + '_cube_plot.png',
                format='png',
                dpi=300,
                bbox_inches='tight')
    fig.clf()
Ejemplo n.º 13
0
def azimuthal_avg_radial_intensity(wave,
                                   imgpath,
                                   source_center,
                                   rtout,
                                   plotname,
                                   annulus_width=10,
                                   group=8,
                                   dstar=200.):

    import numpy as np
    import matplotlib as mpl
    # to avoid X server error
    mpl.use('Agg')
    from astropy.io import ascii, fits
    import matplotlib.pyplot as plt
    from photutils import aperture_photometry as ap
    from photutils import CircularAperture, CircularAnnulus
    from astropy import units as u
    from astropy.coordinates import SkyCoord
    from astropy import wcs
    from hyperion.model import ModelOutput
    import astropy.constants as const
    import os

    pc = const.pc.cgs.value
    AU = const.au.cgs.value

    # source_center = '12 01 36.3 -65 08 53.0'

    # Read in data and set up coversions
    im_hdu = fits.open(imgpath)
    im = im_hdu[1].data
    # error
    if (wave < 200.0) & (wave > 70.0):
        im_err = im_hdu[5].data
    elif (wave > 200.0) & (wave < 670.0):
        im_err = im_hdu[5].data
    else:
        im_err_exten = raw_input(
            'The extension that includes the image error: ')
        im_err = im_hdu[int(im_err_exten)].data

    w = wcs.WCS(im_hdu[1].header)

    coord = SkyCoord(source_center, unit=(u.hourangle, u.deg))
    pixcoord = w.wcs_world2pix(coord.ra.degree, coord.dec.degree, 1)
    pix2arcsec = abs(im_hdu[1].header['CDELT1']) * 3600.
    # convert intensity unit from MJy/sr to Jy/pixel
    factor = 1e6 / 4.25e10 * abs(
        im_hdu[1].header['CDELT1'] * im_hdu[1].header['CDELT2']) * 3600**2

    # radial grid in arcsec
    # annulus_width = 10
    r = np.arange(10, 200, annulus_width, dtype=float)
    I = np.empty_like(r[:-1])
    I_err = np.empty_like(r[:-1])

    # iteration
    for ir in range(len(r) - 1):
        aperture = CircularAnnulus((pixcoord[0], pixcoord[1]),
                                   r_in=r[ir] / pix2arcsec,
                                   r_out=r[ir + 1] / pix2arcsec)
        #     print aperture.r_in
        phot = ap(im, aperture, error=im_err)
        I[ir] = phot['aperture_sum'].data * factor / aperture.area()
        I_err[ir] = phot['aperture_sum_err'].data * factor / aperture.area()
        # print r[ir], I[ir]

    # read in from RTout
    rtout = ModelOutput(rtout)
    # setting up parameters
    # dstar = 200.
    # group = 8
    # wave = 500.0

    im = rtout.get_image(group=group,
                         inclination=0,
                         distance=dstar * pc,
                         units='Jy',
                         uncertainties=True)

    # Find the closest wavelength
    iwav = np.argmin(np.abs(wave - im.wav))
    # avoid zero when log, and flip the image
    val = im.val[::-1, :, iwav]
    unc = im.unc[::-1, :, iwav]

    w = np.degrees(max(rtout.get_quantities().r_wall) / im.distance) * 3600
    npix = len(val[:, 0])
    pix2arcsec = 2 * w / npix

    # radial grid in arcsec
    # annulus_width = 10
    r = np.arange(10, 200, annulus_width, dtype=float)
    I_sim = np.empty_like(r[:-1])
    I_sim_err = np.empty_like(r[:-1])

    # iteration
    for ir in range(len(r) - 1):
        aperture = CircularAnnulus((npix / 2. + 0.5, npix / 2. + 0.5),
                                   r_in=r[ir] / pix2arcsec,
                                   r_out=r[ir + 1] / pix2arcsec)
        #     print aperture.r_in
        phot = ap(val, aperture, error=unc)
        I_sim[ir] = phot['aperture_sum'].data / aperture.area()
        I_sim_err[ir] = phot['aperture_sum_err'].data / aperture.area()
        # print r[ir], I_sim[ir]

    # write the numbers into file
    foo = open(plotname + '_radial_profile_' + str(wave) + 'um.txt', 'w')
    # print some header info
    foo.write('# wavelength ' + str(wave) + ' um \n')
    foo.write('# image file ' + os.path.basename(imgpath) + ' \n')
    foo.write('# annulus width ' + str(annulus_width) + ' arcsec \n')
    # write profiles
    foo.write('r_in[arcsec] \t I \t I_err \t I_sim \t I_sim_err \n')
    for i in range(len(I)):
        foo.write('%f \t %e \t %e \t %e \t %e \n' %
                  (r[i], I[i], I_err[i], I_sim[i], I_sim_err[i]))
    foo.close()

    # plot
    fig = plt.figure(figsize=(8, 6))
    ax = fig.add_subplot(111)

    I_sim_hi = np.log10(
        (I_sim + I_sim_err) / I_sim.max()) - np.log10(I_sim / I_sim.max())
    I_sim_low = np.log10(I_sim / I_sim.max()) - np.log10(
        (I_sim - I_sim_err) / I_sim.max())

    I_hi = np.log10((I + I_err) / I.max()) - np.log10(I / I.max())
    I_low = np.log10(I / I.max()) - np.log10((I - I_err) / I.max())

    i_sim = ax.errorbar(np.log10(r[:-1] * dstar),
                        np.log10(I_sim / I_sim.max()),
                        yerr=(I_sim_low, I_sim_hi),
                        marker='o',
                        linestyle='-',
                        mec='None',
                        markersize=10)
    i = ax.errorbar(np.log10(r[:-1] * dstar),
                    np.log10(I / I.max()),
                    yerr=(I_low, I_hi),
                    marker='o',
                    linestyle='-',
                    mec='None',
                    markersize=10)

    ax.legend([i, i_sim], [r'$\rm{observation}$', r'$\rm{simulation}$'],
              fontsize=16,
              numpoints=1,
              loc='upper right')
    [
        ax.spines[axis].set_linewidth(1.5)
        for axis in ['top', 'bottom', 'left', 'right']
    ]
    ax.minorticks_on()
    ax.tick_params('both',
                   labelsize=18,
                   width=1.5,
                   which='major',
                   pad=10,
                   length=5)
    ax.tick_params('both',
                   labelsize=18,
                   width=1.5,
                   which='minor',
                   pad=10,
                   length=2.5)
    ax.set_xlabel(r'$\rm{log(Radius)\,[AU]}$', fontsize=18)
    ax.set_ylabel(r'$\rm{log(I\,/\,I_{max})}$', fontsize=18)

    # fix the tick label font
    ticks_font = mpl.font_manager.FontProperties(family='STIXGeneral', size=18)
    for label in ax.get_xticklabels():
        label.set_fontproperties(ticks_font)
    for label in ax.get_yticklabels():
        label.set_fontproperties(ticks_font)

    fig.savefig(plotname + '_radial_profile_' + str(wave) + 'um.pdf',
                format='pdf',
                dpi=300,
                bbox_inches='tight')
    fig.clf()
Ejemplo n.º 14
0
def convolve(image_file, filterfilenames, filter_data):

    # Load the model output object
    m = ModelOutput(image_file)

    # Get the image
    image = m.get_image(units='ergs/s')

    # Get image bounds for correct scaling
    w = image.x_max * u.cm
    w = w.to(u.kpc)

    # This is where the convolved images will go
    image_data = []

    # List the filters that shouldn't be used in convolution
    skip_conv = ['arbitrary.filter', 'pdfilters.dat']

    # Loop through the filters and match wavelengths to those in the image
    for i in range(len(filterfilenames)):

        # Skip "arbitrary.filter" if it is selected
        if filterfilenames[i] in skip_conv:
            print(" Skipping convolution of default filter")
            continue

        print("\n Convolving filter {}...".format(filterfilenames[i]))
        wavs = filter_data[i][:, 0]

        # Figure out which indices of the image wavelengths correspond to
        # this filter
        indices = []
        for wav in wavs:
            diffs = np.abs(image.wav - wav)

            # Make sure the closest wavelength is *really* close --- there
            # could be rounding errors, but we don't want to accidentally grab
            # the wrong wavelength
            if min(diffs) <= 1e-10:
                indices.append(diffs.argmin())

        if len(indices) != len(wavs):
            raise ValueError(
                "Filter wavelength mismatch with available image wavelengths")

        # Get the monochromatic images at each wavelength in the filter
        images = [image.val[0, :, :, j] for j in indices]
        print(' Found {} monochromatic images'.format(len(images)))

        # Show wavelengths and weights from filter file
        wavelengths = [image.wav[j] for j in indices]
        weights = filter_data[i][:, 1]

        print('\n Wavelength              Weight')
        print(' ----------              ------')
        for k in range(len(wavelengths)):
            print('  {:.2E}              {:.2E}'.format(
                wavelengths[k], weights[k]))

        # Apply appropriate transmissivities from filter file
        image_data.append(np.average(images, axis=0, weights=weights))

    # Save the image data and filter information as an .hdf5 file
    f = h5py.File(
        cfg.model.PD_output_dir + "convolved." + cfg.model.snapnum_str +
        ".hdf5", "w")
    f.create_dataset("image_data", data=image_data)
    f['image_data'].attrs['width'] = w.value
    f['image_data'].attrs['width_unit'] = np.bytes_('kpc')

    # Don't add the names of filters that were skipped
    trimmed_names = list(set(filterfilenames) - set(skip_conv))
    f.create_dataset("filter_names", data=trimmed_names)

    for i in range(len(filterfilenames)):
        f.create_dataset(filterfilenames[i], data=filter_data[i])
    f.close()
Ejemplo n.º 15
0
filename = '/Users/yaolun/bhr71/hyperion/cycle9/model34.rtout'
outdir = '/Users/yaolun/test/'
dist = 178.
wave = 500.

from hyperion.model import ModelOutput
import astropy.constants as const
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import font_manager
from mpl_toolkits.axes_grid1 import make_axes_locatable

# constant setup
pc = const.pc.cgs.value

m = ModelOutput(filename)
image = m.get_image(group=22,
                    inclination=0,
                    distance=dist * pc,
                    units='MJy/sr')
# Find the closest wavelength
iwav = np.argmin(np.abs(wave - image.wav))

# Calculate the image width in arcseconds given the distance used above
# get the max radius
rmax = max(m.get_quantities().r_wall)
w = np.degrees(rmax / image.distance) * 3600.

# Image in the unit of MJy/sr
# Change it into erg/s/cm2/Hz/sr
factor = 1e-23 * 1e6
Ejemplo n.º 16
0
m.set_spherical_polar_grid(r, t, p)

dens = zeros((nr - 1, nt - 1, np - 1)) + 1.0e-17

m.add_density_grid(dens, d)

source = m.add_spherical_source()
source.luminosity = lsun
source.radius = rsun
source.temperature = 4000.

m.set_n_photons(initial=1000000, imaging=0)
m.set_convergence(True, percentile=99., absolute=2., relative=1.02)

m.write("test_spherical.rtin")

m.run("test_spherical.rtout", mpi=False)

n = ModelOutput('test_spherical.rtout')

grid = n.get_quantities()

temp = grid.quantities['temperature'][0]

for i in range(9):
    plt.imshow(temp[i,:,:],origin="lower",interpolation="nearest", \
            vmin=temp.min(),vmax=temp.max())
    plt.colorbar()
    plt.show()
Ejemplo n.º 17
0
import numpy as np
from PIL import Image

from hyperion.model import ModelOutput
from hyperion.util.constants import pc

m = ModelOutput('simple_cube.rtout')
image = m.get_image(inclination=0, distance=300 * pc, units='MJy/sr')

# Extract the slices we want to use for red, green, and blue
r = image.val[:, :, 17]
g = image.val[:, :, 18]
b = image.val[:, :, 19]

# Now we need to rescale the values we want to the range 0 to 255, clip values
# outside the range, and convert to unsigned 8-bit integers. We also use a sqrt
# stretch (hence the ** 0.5)

r = np.clip((r / 0.5)**0.5 * 255., 0., 255.)
r = np.array(r, dtype=np.uint8)

g = np.clip((g / 2)**0.5 * 255., 0., 255.)
g = np.array(g, dtype=np.uint8)

b = np.clip((b / 4.)**0.5 * 255., 0., 255.)
b = np.array(b, dtype=np.uint8)

# We now convert to image objects
image_r = Image.fromarray(r)
image_g = Image.fromarray(g)
image_b = Image.fromarray(b)
Ejemplo n.º 18
0
import matplotlib.pyplot as plt

from hyperion.model import ModelOutput
from hyperion.util.constants import pc

mo = ModelOutput('class1_example.rtout')
sed = mo.get_sed(aperture=-1, distance=140. * pc)

fig = plt.figure(figsize=(5, 4))
ax = fig.add_subplot(1, 1, 1)
ax.loglog(sed.wav, sed.val.transpose(), color='black')
ax.set_xlim(0.03, 2000.)
ax.set_ylim(2.e-15, 1e-8)
ax.set_xlabel(r'$\lambda$ [$\mu$m]')
ax.set_ylabel(r'$\lambda F_\lambda$ [ergs/cm$^2/s$]')
fig.savefig('class1_example_sed.png', bbox_inches='tight')
Ejemplo n.º 19
0
def DIG_source_add(m,reg,df_nu):

    print("--------------------------------\n")
    print("Adding DIG to Source List in source_creation\n")
    print("--------------------------------\n")

    print ("Getting specific energy dumped in each grid cell")

    try:
        rtout = cfg.model.outputfile + '.sed'
        try: 
            grid_properties = np.load(cfg.model.PD_output_dir+"/grid_physical_properties."+cfg.model.snapnum_str+'_galaxy'+cfg.model.galaxy_num_str+".npz")
        except:
            grid_properties = np.load(cfg.model.PD_output_dir+"/grid_physical_properties."+cfg.model.snapnum_str+".npz")

        cell_info = np.load(cfg.model.PD_output_dir+"/cell_info."+cfg.model.snapnum_str+"_"+cfg.model.galaxy_num_str+".npz")
    except:
        print ("ERROR: Can't proceed with DIG nebular emission calculation. Code is unable to find the required files.") 
        print ("Make sure you have the rtout.sed, grid_physical_properties.npz and cell_info.npz for the corresponding galaxy.")

        return 

    m_out = ModelOutput(rtout)
    oct = m_out.get_quantities()
    grid = oct
    order = find_order(grid.refined)
    refined = grid.refined[order]
    quantities = {}
    for field in grid.quantities:
        quantities[('gas', field)] = grid.quantities[field][0][order][~refined]

    cell_width = cell_info["fw1"][:,0]
    mass = (quantities['gas','density']*units.g/units.cm**3).value * (cell_width**3)
    met = grid_properties["grid_gas_metallicity"]
    specific_energy = (quantities['gas','specific_energy']*units.erg/units.s/units.g).value
    specific_energy = (specific_energy * mass) # in ergs/s

    # Black 1987 curve has a integrated ergs/s/cm2 of 0.0278 so the factor we need to multiply it by is given by this value
    factor = specific_energy/(cell_width**2)/(0.0278) 

    mask1 = np.where(mass != 0 )[0]
    mask = np.where((mass != 0 ) & (factor >= cfg.par.DIG_min_factor))[0] # Masking out all grid cells that have no gas mass and where the specific emergy is too low
    print (len(factor), len(mask1), len(mask))
    
    factor = factor[mask]
    cell_width = cell_width[mask]
    cell_x = (cell_info["xmax"] - cell_info["xmin"])[mask]
    cell_y = (cell_info["ymax"] - cell_info["ymin"])[mask]
    cell_z = (cell_info["zmax"] - cell_info["zmin"])[mask]
    pos = np.vstack([cell_x, cell_y, cell_z]).transpose()

    met = grid_properties["grid_gas_metallicity"][:, mask]
    met = np.transpose(met)
    
    fnu_arr = sg.get_dig_seds(factor, cell_width, met)
    
    dat = np.load(cfg.par.pd_source_dir + "/powderday/nebular_emission/data/black_1987.npz")
    spec_lam = dat["lam"]
    nu = 1.e8 * constants.c.cgs.value / spec_lam 

    for i in range(len(factor)):
        fnu = fnu_arr[i,:]
        nu, fnu = wavelength_compress(nu,fnu,df_nu)
        
        nu = nu[::-1]
        fnu = fnu[::-1]
        
        lum = np.absolute(np.trapz(fnu,x=nu))*constants.L_sun.cgs.value
        
        source = m.add_point_source()
        source.luminosity = lum # [ergs/s]
        source.spectrum = (nu,fnu)
        source.position = pos[i] # [cm]
import numpy as np
import matplotlib.pyplot as plt
from hyperion.model import ModelOutput
import astropy.units as u

# ------------------------
# modifiable header
# ------------------------

m = ModelOutput('/Users/desika/Dropbox/powderday/verification/gadget/example.200.rtout.image')
wav = 200  # micron

# ------------------------

# Get the image from the ModelOutput object
image = m.get_image(units='ergs/s')

# Open figure and create axes
fig = plt.figure()
ax = fig.add_subplot(111)

# Find the closest wavelength
iwav = np.argmin(np.abs(wav - image.wav))

# Calculate the image width in kpc
w = image.x_max * u.cm
w = w.to(u.kpc)

# plot the beast
cax = ax.imshow(np.log(image.val[0, :, :, iwav]), cmap=plt.cm.viridis,
                origin='lower', extent=[-w.value, w.value, -w.value, w.value])
Ejemplo n.º 21
0
import numpy as np
import matplotlib.pyplot as plt

from hyperion.model import ModelOutput
from hyperion.util.integrate import integrate_loglog

# Use LaTeX for plots
plt.rc('text', usetex=True)

# Open the output file
m = ModelOutput('example_isrf.rtout')

# Get an all-sky flux map
image = m.get_image(units='ergs/cm^2/s/Hz', inclination=0)

# Compute the frequency-integrated flux
fint = np.zeros(image.val.shape[:-1])
for (j, i) in np.ndindex(fint.shape):
    fint[j, i] = integrate_loglog(image.nu, image.val[j, i, :])

# Find the area of each pixel
l = np.radians(np.linspace(180., -180., fint.shape[1] + 1))
b = np.radians(np.linspace(-90., 90., fint.shape[0] + 1))
dl = l[1:] - l[:-1]
db = np.sin(b[1:]) - np.sin(b[:-1])
DL, DB = np.meshgrid(dl, db)
area = np.abs(DL * DB)

# Compute the intensity
intensity = fint / area
snap = '078'
z = 2.025

with open('m100_sed/galaxy_selection.json', 'r') as fp:
    _dat = json.load(fp)[snap]
    gidx = list(_dat.keys())
    hidx = np.array([int(h['hidx']) for k, h in _dat.items()])
    #_coods = [h['lcone_pos'] for k,h in _dat.items()]

for _gidx in ['3']:  #gidx:

    # snap_fname = f'{rt_directory}/snap_{snap}/gal_{_gidx}/snap{snap}.galaxy*.rtout.sed'
    snap_fname = f'{rt_directory}/snap_{snap}/gal_{_gidx}/snap{snap}.galaxy*.rtout.sed'
    fname = glob.glob(snap_fname)[0]

    m = ModelOutput(filename=fname)  #,group='00000')
    wav, lum = m.get_sed(inclination='all', aperture=-1)

    ## High res
    snap_fname = f'{rt_directory}/snap_{snap}_hires/gal_{_gidx}/snap{snap}.galaxy*.rtout.sed'
    fname = glob.glob(snap_fname)[0]

    m = ModelOutput(filename=fname)  #,group='00000')
    wav_hr, lum_hr = m.get_sed(inclination='all', aperture=-1)

    # with h5py.File('sed_out.h5','a') as f:
    #     f.create_group(_gidx)
    #     dset = f.create_dataset('%s/Wavelength'%_gidx, data=wav)
    #     dset.attrs['Units'] = 'microns'
    #     dset = f.create_dataset('%s/SED'%_gidx, data=lum)
    #     dset.attrs['Units'] = 'erg/s'
dust_mass_Msun = []
sfr100 = []
metallicity_logzsol = []
gal_count = []
filter_list = []

pd_list = glob.glob(pd_dir+'/*.rtout.sed')
snap_num = int(pd_list[0].split('snap')[2].split('.')[0])
print('loading galaxy list')
galaxy_list = []
for i in pd_list:
    galaxy_list.append(int(i.split('.')[2].split('galaxy')[1]))

for galaxy in tqdm.tqdm(galaxy_list):
    
    m = ModelOutput(pd_dir+'/snap'+str(snap_num)+'.galaxy'+str(galaxy)+'.rtout.sed')
    ds = yt.load(snaps_dir+'/galaxy_'+str(galaxy)+'.hdf5', 'r') 
    wave, flx = m.get_sed(inclination=0, aperture=-1)
    
    gal_count.append(galaxy)
    
    #get mock photometry
    wave  = np.asarray(wave)*u.micron 
    if obs_frame:
        wav = wave[::-1].to(u.AA)*(1 + float(z))
    else:
        wav = wave[::-1].to(u.AA)
    flux = np.asarray(flx)[::-1]*u.erg/u.s
    if float(z) == 0.0:
        dl = (10*u.pc).to(u.cm)
    else:
Ejemplo n.º 24
0
def alma_cavity(freq,
                outdir,
                vlim,
                units='MJy/sr',
                pix=300,
                filename=None,
                label=None):
    import numpy as np
    import matplotlib.pyplot as plt
    import astropy.constants as const
    from hyperion.model import ModelOutput
    from matplotlib.ticker import MaxNLocator

    # constants setup
    c = const.c.cgs.value
    pc = const.pc.cgs.value
    au = const.au.cgs.value
    # Image in the unit of MJy/sr
    # Change it into erg/s/cm2/Hz/sr
    if units == 'erg/s/cm2/Hz/sr':
        factor = 1e-23 * 1e6
        cb_label = r'$\rm{I_{\nu}\,(erg\,s^{-1}\,cm^{-2}\,Hz^{-1}\,sr^{-1})}$'
    elif units == 'MJy/sr':
        factor = 1
        cb_label = r'$\rm{I_{\nu}\,(MJy\,sr^{-1})}$'

    if filename == None:
        # input files setup
        filename_reg = '/Users/yaolun/test/model12.rtout'
        filename_r2 = '/Users/yaolun/test/model13.rtout'
        filename_r15 = '/Users/yaolun/test/model17.rtout'
        filename_uni = '/Users/yaolun/test/model62.rtout'
    else:
        filename_reg = filename['reg']
        filename_r2 = filename['r2']
        filename_r15 = filename['r15']
        filename_uni = filename['uni']

    if label == None:
        label_reg = r'$\rm{const.+r^{-2}}$'
        label_r2 = r'$\rm{r^{-2}}$'
        label_r15 = r'$\rm{r^{-1.5}}$'
        label_uni = r'$\rm{uniform}$'
    else:
        label_reg = label['reg']
        label_r2 = label['r2']
        label_r15 = label['r15']
        label_uni = label['uni']

    wl_aper = [
        3.6, 4.5, 5.8, 8.0, 8.5, 9, 9.7, 10, 10.5, 11, 16, 20, 24, 35, 70, 100,
        160, 250, 350, 500, 850
    ]
    wav = c / freq / 1e9 * 1e4
    # wav = 40

    # read in
    # regular cavity setting
    m_reg = ModelOutput(filename_reg)
    image_reg = m_reg.get_image(group=len(wl_aper) + 1,
                                inclination=0,
                                distance=178.0 * pc,
                                units='MJy/sr')
    # Calculate the image width in arcseconds given the distance used above
    rmax = max(m_reg.get_quantities().r_wall)
    w = np.degrees(rmax / image_reg.distance) * 3600.
    # w = np.degrees((1.5 * pc) / image_reg.distance) * 60.
    pix_num = len(image_reg.val[:, 0, 0])
    pix2arcsec = 2 * w / pix_num
    pix2au = np.radians(2 * w / pix_num / 3600.) * image_reg.distance / au

    iwav = np.argmin(np.abs(wav - image_reg.wav))
    # avoid zero in log
    val_reg = image_reg.val[:, :, iwav] * factor + 1e-30

    # r^-2 cavity setting
    m_r2 = ModelOutput(filename_r2)
    image_r2 = m_r2.get_image(group=len(wl_aper) + 1,
                              inclination=0,
                              distance=178.0 * pc,
                              units='MJy/sr')
    # Calculate the image width in arcseconds given the distance used above
    rmax = max(m_r2.get_quantities().r_wall)
    w = np.degrees(rmax / image_r2.distance) * 3600.
    pix_num = len(image_reg.val[:, 0, 0])
    pix2arcsec = 2 * w / pix_num
    pix2au = np.radians(2 * w / pix_num / 3600.) * image_reg.distance / au
    iwav = np.argmin(np.abs(wav - image_r2.wav))
    # avoid zero in log
    val_r2 = image_r2.val[:, :, iwav] * factor + 1e-30

    # r^-1.5 cavity setting
    m_r15 = ModelOutput(filename_r15)
    image_r15 = m_r15.get_image(group=len(wl_aper) + 1,
                                inclination=0,
                                distance=178.0 * pc,
                                units='MJy/sr')
    # Calculate the image width in arcseconds given the distance used above
    rmax = max(m_r15.get_quantities().r_wall)
    w = np.degrees(rmax / image_r15.distance) * 3600.
    pix_num = len(image_reg.val[:, 0, 0])
    pix2arcsec = 2 * w / pix_num
    pix2au = np.radians(2 * w / pix_num / 3600.) * image_reg.distance / au
    iwav = np.argmin(np.abs(wav - image_r15.wav))
    # avoid zero in log
    val_r15 = image_r15.val[:, :, iwav] * factor + 1e-30

    # uniform cavity setting
    m_uni = ModelOutput(filename_uni)
    image_uni = m_uni.get_image(group=len(wl_aper) + 1,
                                inclination=0,
                                distance=178.0 * pc,
                                units='MJy/sr')
    # Calculate the image width in arcseconds given the distance used above
    rmax = max(m_uni.get_quantities().r_wall)
    w = np.degrees(rmax / image_uni.distance) * 3600.
    print w
    pix_num = len(image_reg.val[:, 0, 0])
    pix2arcsec = 2 * w / pix_num
    pix2au = np.radians(2 * w / pix_num / 3600.) * image_reg.distance / au
    iwav = np.argmin(np.abs(wav - image_uni.wav))
    # avoid zero in log
    val_uni = image_uni.val[:, :, iwav] * factor + 1e-30

    # 1-D radial intensity profile
    # get y=0 plane, and plot it
    fig = plt.figure(figsize=(8, 6))
    ax = fig.add_subplot(111)

    reg, = ax.plot(np.linspace(-pix / 2, pix / 2, num=pix) * pix2arcsec,
                   val_reg[:, pix / 2 - 1],
                   color='b',
                   linewidth=2)
    r2, = ax.plot(np.linspace(-pix / 2, pix / 2, num=pix) * pix2arcsec,
                  val_r2[:, pix / 2 - 1],
                  color='r',
                  linewidth=1.5)
    r15, = ax.plot(np.linspace(-pix / 2, pix / 2, num=pix) * pix2arcsec,
                   val_r15[:, pix / 2 - 1],
                   '--',
                   color='r',
                   linewidth=1.5)
    uni, = ax.plot(np.linspace(-pix / 2, pix / 2, num=pix) * pix2arcsec,
                   val_uni[:, pix / 2 - 1],
                   color='k',
                   linewidth=1.5)
    ax.legend([reg, r2, r15, uni], [label_reg, label_r2, label_r15, label_uni],\
              numpoints=1, loc='lower center', fontsize=18)

    ax.set_xlim([-1, 1])
    ax.set_xlabel(r'$\rm{offset\,(arcsec)}$', fontsize=24)
    # ax.set_ylabel(r'$\rm{I_{\nu}~(erg~s^{-1}~cm^{-2}~Hz^{-1}~sr^{-1})}$', fontsize=16)
    ax.set_ylabel(cb_label, fontsize=24)

    [
        ax.spines[axis].set_linewidth(2)
        for axis in ['top', 'bottom', 'left', 'right']
    ]
    ax.minorticks_on()
    ax.tick_params('both',
                   labelsize=16,
                   width=2,
                   which='major',
                   pad=10,
                   length=5)
    ax.tick_params('both',
                   labelsize=16,
                   width=2,
                   which='minor',
                   pad=10,
                   length=2.5)

    fig.savefig(outdir + 'cavity_intensity_' + str(freq) + '.pdf',
                format='pdf',
                dpi=300,
                bbox_inches='tight')

    # 2-D intensity map
    from mpl_toolkits.axes_grid1 import AxesGrid
    image_grid = [val_reg, val_uni, val_r2, val_r15]
    label_grid = [label_reg, label_r2, label_r15, label_uni]
    fig = plt.figure(figsize=(30, 30))
    grid = AxesGrid(
        fig,
        142,  # similar to subplot(142)
        nrows_ncols=(2, 2),
        axes_pad=0,
        share_all=True,
        label_mode="L",
        cbar_location="right",
        cbar_mode="single",
    )
    for i in range(4):
        offset = np.linspace(-pix / 2, pix / 2, num=pix) * pix2arcsec
        trim = np.where(abs(offset) <= 2)
        im = grid[i].pcolor(np.linspace(-pix/2,pix/2,num=pix)*pix2arcsec, np.linspace(-pix/2,pix/2,num=pix)*pix2arcsec,\
            image_grid[i], cmap=plt.cm.jet, vmin=vlim[0], vmax=vlim[1])#vmin=(image_grid[i][trim,trim]).min(), vmax=(image_grid[i][trim,trim]).max())
        grid[i].set_xlim([-20, 20])
        grid[i].set_ylim([-20, 20])
        grid[i].set_xlabel(r'$\rm{RA\,offset\,(arcsec)}$', fontsize=14)
        grid[i].set_ylabel(r'$\rm{Dec\,offset\,(arcsec)}$', fontsize=14)
        # lg = grid[i].legend([label_grid[i]], loc='upper center', numpoints=1, fontsize=16)
        # for text in lg.get_texts():
        #     text.set_color('w')
        grid[i].text(0.5,
                     0.8,
                     label_grid[i],
                     color='w',
                     weight='heavy',
                     fontsize=18,
                     transform=grid[i].transAxes,
                     ha='center')
        grid[i].locator_params(axis='x', nbins=5)
        grid[i].locator_params(axis='y', nbins=5)
        [
            grid[i].spines[axis].set_linewidth(1.2)
            for axis in ['top', 'bottom', 'left', 'right']
        ]
        grid[i].tick_params('both',
                            labelsize=12,
                            width=1.2,
                            which='major',
                            pad=10,
                            color='white',
                            length=5)
        grid[i].tick_params('both',
                            labelsize=12,
                            width=1.2,
                            which='minor',
                            pad=10,
                            color='white',
                            length=2.5)

        # fix the overlap tick labels
        if i != 0:
            x_nbins = len(grid[i].get_xticklabels())
            y_nbins = len(grid[i].get_yticklabels())
            grid[i].yaxis.set_major_locator(MaxNLocator(nbins=5,
                                                        prune='upper'))
            if i != 2:
                grid[i].xaxis.set_major_locator(
                    MaxNLocator(nbins=5, prune='lower'))

    [grid[0].spines[axis].set_color('white') for axis in ['bottom', 'right']]
    [grid[1].spines[axis].set_color('white') for axis in ['bottom', 'left']]
    [grid[2].spines[axis].set_color('white') for axis in ['top', 'right']]
    [grid[3].spines[axis].set_color('white') for axis in ['top', 'left']]

    #     ax.set_aspect('equal')
    cb = grid.cbar_axes[0].colorbar(im)
    cb.solids.set_edgecolor("face")
    cb.ax.minorticks_on()
    cb.ax.set_ylabel(cb_label, fontsize=12)
    cb_obj = plt.getp(cb.ax.axes, 'yticklabels')
    plt.setp(cb_obj, fontsize=12)

    # fig.text(0.5, -0.05 , r'$\rm{RA~offset~(arcsec)}$', fontsize=12, ha='center')
    # fig.text(0, 0.5, r'$\rm{Dec~offset~(arcsec)}$', fontsize=12, va='center', rotation='vertical')

    fig.savefig(outdir + 'cavity_2d_intensity_' + str(freq) + '.png',
                format='png',
                dpi=300,
                bbox_inches='tight')
Ejemplo n.º 25
0
def temp_hyperion(rtout,outdir, bb_dust=False):
    import numpy as np
    import matplotlib as mpl
    mpl.use('Agg')
    import matplotlib.pyplot as plt
    import os
    from hyperion.model import ModelOutput
    import astropy.constants as const
    from matplotlib.colors import LogNorm

    # seaborn colormap
    import seaborn.apionly as sns

    # constants setup
    AU = const.au.cgs.value

    # misc variable setup
    print_name = os.path.splitext(os.path.basename(rtout))[0]

    m = ModelOutput(rtout)
    q = m.get_quantities()

    # get the grid info
    ri, thetai = q.r_wall, q.t_wall
    rc     = 0.5*( ri[0:len(ri)-1]     + ri[1:len(ri)] )
    thetac = 0.5*( thetai[0:len(thetai)-1] + thetai[1:len(thetai)] )

    # get the temperature profile
    # and average across azimuthal angle
    # temperature array in [phi, theta, r]
    temp = q['temperature'][0].array.T
    temp2d = np.sum(temp**2, axis=2)/np.sum(temp, axis=2)
    temp2d_exp = np.hstack((temp2d,temp2d,temp2d[:,0:1]))
    thetac_exp = np.hstack((thetac-np.pi/2, thetac+np.pi/2, thetac[0]-np.pi/2))

    mag = 1
    fig = plt.figure(figsize=(mag*8,mag*6))
    ax = fig.add_subplot(111, projection='polar')

    # cmap = sns.cubehelix_palette(light=1, as_cmap=True)
    cmap = plt.cm.CMRmap
    im = ax.pcolormesh(thetac_exp, rc/AU, temp2d_exp, cmap=cmap, norm=LogNorm(vmin=5, vmax=100))
    #
    # cmap = plt.cm.RdBu_r
    # im = ax.pcolormesh(thetac_exp, np.log10(rc/AU), temp2d_exp/10, cmap=cmap, norm=LogNorm(vmin=0.1, vmax=10))
    #
    print temp2d_exp.min(), temp2d_exp.max()
    im.set_edgecolor('face')

    ax.set_xlabel(r'$\rm{Polar\,angle\,(Degree)}$',fontsize=20)
    # ax.set_ylabel(r'$\rm{Radius\,(AU)}$',fontsize=20, labelpad=-140, color='grey')
    # ax.set_ylabel('',fontsize=20, labelpad=-140, color='grey')
    ax.tick_params(labelsize=16)
    ax.tick_params(axis='y', colors='grey')
    ax.set_yticks(np.hstack((np.arange(0,(int(max(rc)/AU/10000.)+1)*10000, 10000),max(rc)/AU)))
    #
    # ax.set_yticks(np.log10(np.array([1, 10, 100, 1000, 10000, max(rc)/AU])))
    #
    ax.set_yticklabels([])
    ax.grid(True, color='LightGray', linewidth=1.5)
    # ax.grid(True, color='k', linewidth=1)

    ax.set_xticklabels([r'$\rm{90^{\circ}}$',r'$\rm{45^{\circ}}$',r'$\rm{0^{\circ}}$',r'$\rm{-45^{\circ}}$',\
                            r'$\rm{-90^{\circ}}$',r'$\rm{-135^{\circ}}$',r'$\rm{180^{\circ}}$',r'$\rm{135^{\circ}}$'])
    cb = fig.colorbar(im, pad=0.1)
    cb.ax.set_ylabel(r'$\rm{Averaged\,Temperature\,(K)}$',fontsize=20)
    cb.set_ticks([5,10,20,30,40,50,60,70,80,90,100])
    cb.set_ticklabels([r'$\rm{5}$',r'$\rm{10}$',r'$\rm{20}$',r'$\rm{30}$',r'$\rm{40}$',r'$\rm{50}$',r'$\rm{60}$',r'$\rm{70}$',r'$\rm{80}$',r'$\rm{90}$',r'$\rm{>100}$'])
    #
    # cb.ax.set_ylabel(r'$\rm{log(T/10)}$',fontsize=20)
    # cb.set_ticks([0.1, 10**-0.5, 1, 10**0.5, 10])
    # cb.set_ticklabels([r'$\rm{-1}$',r'$\rm{-0.5}$',r'$\rm{0}$',r'$\rm{0.5}$',r'$\rm{\geq 1}$'])
    #
    cb_obj = plt.getp(cb.ax.axes, 'yticklabels')
    plt.setp(cb_obj,fontsize=20)

    # fix the tick label font
    ticks_font = mpl.font_manager.FontProperties(family='STIXGeneral',size=20)
    for label in ax.get_yticklabels():
        label.set_fontproperties(ticks_font)

    fig.savefig(outdir+print_name+'_temperature.png', format='png', dpi=300, bbox_inches='tight')
    fig.clf()

    # Plot the radial temperature profile
    fig = plt.figure(figsize=(12,9))
    ax = fig.add_subplot(111)

    plot_grid = [0,99,199]
    label_grid = [r'$\rm{outflow}$', r'$\rm{45^{\circ}}$', r'$\rm{midplane}$']
    alpha = np.linspace(0.3,1.0,len(plot_grid))
    color_list = [[0.8507598215729224, 0.6322174528970308, 0.6702243543099417],\
                  [0.5687505862870377, 0.3322661256969763, 0.516976691731939],\
                  [0.1750865648952205, 0.11840023306916837, 0.24215989137836502]]

    for i in plot_grid:
        temp_rad, = ax.plot(np.log10(rc/AU), np.log10(temp2d[:,i]),'-',color=color_list[plot_grid.index(i)],\
                            linewidth=2, markersize=3,label=label_grid[plot_grid.index(i)])

    # plot the theoretical prediction for black body dust without considering the extinction
    if bb_dust == True:
        from hyperion.model import Model
        sigma = const.sigma_sb.cgs.value
        lsun = const.L_sun.cgs.value

        dum = Model()
        dum.use_sources(rtout)
        L_cen = dum.sources[0].luminosity/lsun

        t_bbdust = (L_cen*lsun/(16*np.pi*sigma*rc**2))**(0.25)
        temp_bbdust, = ax.plot(np.log10(rc/AU), np.log10(t_bbdust), '--', color='r', linewidth=2.5,label=r'$\rm{blackbody\,dust}$')

    ax.legend(loc='upper right', numpoints=1, fontsize=24)
    ax.set_xlabel(r'$\rm{log\,R\,(AU)}$',fontsize=24)
    ax.set_ylabel(r'$\rm{log\,T\,(K)}$',fontsize=24)
    [ax.spines[axis].set_linewidth(2) for axis in ['top','bottom','left','right']]
    ax.minorticks_on()
    ax.tick_params('both',labelsize=24,width=2,which='major',pad=15,length=5)
    ax.tick_params('both',labelsize=24,width=2,which='minor',pad=15,length=2.5)

    # fix the tick label font
    ticks_font = mpl.font_manager.FontProperties(family='STIXGeneral',size=24)
    for label in ax.get_xticklabels():
        label.set_fontproperties(ticks_font)
    for label in ax.get_yticklabels():
        label.set_fontproperties(ticks_font)

    ax.set_ylim([0,4])
    fig.gca().set_xlim(left=np.log10(0.05))
    # ax.set_xlim([np.log10(0.8),np.log10(10000)])

    fig.savefig(outdir+print_name+'_temp_radial.pdf',format='pdf',dpi=300,bbox_inches='tight')
    fig.clf()
Ejemplo n.º 26
0
        source_lam_downsampled[i] = source_lam[idx].value
        lum_source_downsampled[i] = lum_source[idx].value

    return source_lam_downsampled, lum_source_downsampled


#check if path exists - if not, create it
#if not os.path.exists(output_directory): os.makedirs(output_directory)

sed_file = glob(sed_directory + '/*galaxy' + str(galaxy_num) + '.rtout.sed')[0]
#print(sed_file)

stellar_file = glob(sources_directory + '/*.galaxy' + str(galaxy_num) +
                    '.rtout.sed')[0]

comp_sed = ModelOutput(sed_file)
wav_rest_sed, dum_lum_obs_sed = comp_sed.get_sed(inclination='all',
                                                 aperture=-1)
wav_rest_sed = wav_rest_sed * u.micron  #wav is in micron
nu_rest_sed = constants.c.cgs / wav_rest_sed.cgs
lum_obs_sed = dum_lum_obs_sed
lum_obs_sed = lum_obs_sed * u.erg / u.s
nu_rest_sed = constants.c.cgs / (wav_rest_sed.to(u.cm))
fnu_obs_sed = lum_obs_sed.to(u.Lsun)
fnu_obs_sed /= nu_rest_sed.to(u.Hz)
fnu_obs_sed = fnu_obs_sed.to(u.Lsun / u.Hz)

#stellar_sed = np.load(stellar_file)
#nu_rest_stellar = stellar_sed['nu'] #Hz
#fnu_rest_stellar = stellar_sed['fnu'] #Lsun/Hz
#fnu_rest_stellar = fnu_rest_stellar * u.Lsun/u.Hz
Ejemplo n.º 27
0
import os

import numpy as np
import matplotlib.pyplot as plt

from hyperion.model import ModelOutput
from hyperion.util.constants import pc

# Create output directory if it does not already exist
if not os.path.exists('frames'):
    os.mkdir('frames')

# Open model
m = ModelOutput('flyaround_cube.rtout')

# Read image from model
image = m.get_image(distance=300 * pc, units='MJy/sr')

# image.val is now an array with four dimensions (n_view, n_y, n_x, n_wav)

for iview in range(image.val.shape[0]):

    # Open figure and create axes
    fig = plt.figure(figsize=(3, 3))
    ax = fig.add_subplot(1, 1, 1)

    # This is the command to show the image. The parameters vmin and vmax are
    # the min and max levels for the grayscale (remove for default values).
    # The colormap is set here to be a heat map. Other possible heat maps
    # include plt.cm.gray (grayscale), plt.cm.gist_yarg (inverted grayscale),
    # plt.cm.jet (default, colorful). The np.sqrt() is used to plot the
Ejemplo n.º 28
0
import matplotlib.pyplot as plt

from hyperion.model import ModelOutput
from hyperion.util.constants import pc

m = ModelOutput('class2_sed.rtout')

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)

# Total SED
sed = m.get_sed(inclination=0, aperture=-1, distance=300 * pc)
ax.loglog(sed.wav, sed.val, color='black', lw=3, alpha=0.5)

# Direct stellar photons
sed = m.get_sed(inclination=0, aperture=-1, distance=300 * pc,
                       component='source_emit')
ax.loglog(sed.wav, sed.val, color='blue')

# Scattered stellar photons
sed = m.get_sed(inclination=0, aperture=-1, distance=300 * pc,
                       component='source_scat')
ax.loglog(sed.wav, sed.val, color='teal')

# Direct dust photons
sed = m.get_sed(inclination=0, aperture=-1, distance=300 * pc,
                       component='dust_emit')
ax.loglog(sed.wav, sed.val, color='red')

# Scattered dust photons
sed = m.get_sed(inclination=0, aperture=-1, distance=300 * pc,
Ejemplo n.º 29
0
#Script showing how to extract some rtout files that were run on an
#octree format

from __future__ import print_function
from hyperion.model import ModelOutput
from hyperion.grid.yt3_wrappers import find_order
import astropy.units as u
import numpy as np

run = '/home/desika.narayanan/pd_git/tests/SKIRT/gizmo_mw_zoom/pd_skirt_comparison.134.rtout.sed'

m = ModelOutput(run)


oct = m.get_quantities()
#ds = oct.to_yt()

#ripped from hyperion/grid/yt3_wrappers.py -- we do this because
#something about load_octree in yt4.x is only returning the first cell
grid = oct
order = find_order(grid.refined)
refined = grid.refined[order]

quantities = {}
for field in grid.quantities:
    quantities[('gas', field)] = np.atleast_2d(grid.quantities[field][0][order][~refined]).transpose()

specific_energy = quantities['gas','specific_energy']*u.erg/u.s/u.g
dust_temp = quantities['gas','temperature']*u.K
dust_density = quantities['gas','density']*u.g/u.cm**3
Ejemplo n.º 30
0
    type=float,
    help='A single wavelength in microns, if producing a monochromatic image.')
parser.add_argument('-d',
                    '--dat',
                    action='store_true',
                    help='If enabled, saves a ".dat" file with image data.')
parser.add_argument('--vmin',
                    type=float,
                    help='Minimum of colorbar scale, in units of ergs/s.')
parser.add_argument('--vmax',
                    type=float,
                    help='Maximum of colorbar scale, in units of ergs/s.')

args = parser.parse_args()

m = ModelOutput(pathch(args.infile))

if args.outfile is None:
    args.outfile = os.path.dirname(args.infile)

# Extract the image for the first inclination, and scale to 300pc. We
# have to specify group=1 as there is no image in group 0.
image = m.get_image(units='ergs/s')

# Open figure and create axes
fig = plt.figure()
ax = fig.add_subplot(111)

# Calculate the image width in kpc
w = image.x_max * u.cm
w = w.to(u.kpc)