Exemplo n.º 1
0
import numpy as np

from hyperion.model import Model
from hyperion.util.constants import pc, lsun

# Initialize model
m = Model()

# Set one-cell cartesian grid
w = np.linspace(-pc, pc, 32)
m.set_cartesian_grid(w, w, w)

# Add density grid with constant density
m.add_density_grid(np.ones(m.grid.shape) * 4.e-20, 'kmh_lite.hdf5')

# Add a point source in the center
s = m.add_point_source()
s.luminosity = 1000 * lsun
s.temperature = 6000.

# Add 10 SEDs for different viewing angles
image = m.add_peeled_images(sed=True, image=False)
image.set_wavelength_range(250, 0.01, 5000.)
image.set_viewing_angles(np.linspace(0., 90., 10), np.repeat(20., 10))
image.set_track_origin('basic')

# Add multi-wavelength image for a single viewing angle
image = m.add_peeled_images(sed=False, image=True)
image.set_wavelength_range(30, 1., 1000.)
image.set_viewing_angles([30.], [20.])
image.set_image_size(200, 200)
Exemplo n.º 2
0
import numpy as np
from hyperion.model import Model
from hyperion.util.constants import au, lsun, rsun
from hyperion.dust import SphericalDust


# Model
m = Model()
dist = 20000 * au
x = np.linspace(-dist, dist, 101)
y = np.linspace(-dist, dist, 101)
z = np.linspace(-dist, dist, 101)
m.set_cartesian_grid(x,y,z)

# Dust
d = SphericalDust('kmh.hdf5')
d.set_sublimation_temperature('fast', temperature=1600.)
m.add_density_grid(np.ones((100,100,100)) * 1.e-18,'kmh.hdf5')

# Alpha centauri
sourceA = m.add_spherical_source()
sourceA.luminosity = 1.519 * lsun
sourceA.radius = 1.227 * rsun
sourceA.temperature = 5790.
sourceA.position = (0., 0., 0.)

# Beta centauri
sourceB = m.add_spherical_source()
sourceB.luminosity = 0.5 * lsun
sourceB.radius = 0.865 * rsun
sourceB.temperature = 5260.
# A simple model with no dust, just sources, to check that the Doppler Shifting
# is working correctly. This model consists of a disk of sources that is
# rotating in a solid body fashion around the origin. All sources have a
# spectrum that consists of a single spectral line that is narrow enough that we
# can easily see the rotation in a multi-wavelength image. We check that the
# image looks sensible in both binned and peeled images.

# Same as setup_indiv but using a point source collection

import numpy as np
from hyperion.model import Model
from hyperion.util.constants import c

m = Model()

m.set_cartesian_grid([-1., 1], [-1., 1.], [-1., 1])

N = 100000
w = np.random.random(N)**0.5
p = np.random.uniform(0, 2 * np.pi, N)
z = np.random.uniform(-0.1, 0.1, N)

x = w * np.cos(p)
y = w * np.sin(p)

# solid body with 1000 km/s on the outside
v = w * 1e8  # cm / s

vx = - v * np.sin(p)
vy = + v * np.cos(p)
vz = np.repeat(0, N)
Exemplo n.º 4
0
import numpy as np

from hyperion.model import Model
from hyperion.util.constants import pc, lsun

# Initialize model
m = Model()

# Set up 64x64x64 cartesian grid
w = np.linspace(-pc, pc, 64)
m.set_cartesian_grid(w, w, w)

# Add density grid with constant density and add a higher density cube inside to
# cause a shadow.
density = np.ones(m.grid.shape) * 1e-21
density[26:38, 26:38, 26:38] = 1.e-18
m.add_density_grid(density, 'kmh_lite.hdf5')

# Add a point source in the center
s = m.add_point_source()
s.position = (0.4 * pc, 0., 0.)
s.luminosity = 1000 * lsun
s.temperature = 6000.

# Add multi-wavelength image for a single viewing angle
image = m.add_peeled_images(sed=False, image=True)
image.set_wavelength_range(1, 190., 210.)
image.set_viewing_angles(np.repeat(45., 36), np.linspace(5., 355., 36))
image.set_image_size(400, 400)
image.set_image_limits(-1.5 * pc, 1.5 * pc, -1.5 * pc, 1.5 * pc)
# A simple model to check what happens when a source is moving towards dust and
# we observe both the source and the dust. If we observe the source such that
# the dust is directly behind, and the source is moving towards the dust, we
# should see red-shifted emission from the source and blue-shifted scattered
# light emission.

import numpy as np
from hyperion.model import Model
from hyperion.util.constants import c

m = Model()

m.set_cartesian_grid([-1., 0, 1], [-1., 1.], [-1., 1])

density = np.zeros(m.grid.shape)
density[:, :, 0] = 1.

m.add_density_grid(density, 'kmh_lite.hdf5')

# narrow emission line spectrum at 1 micron
wav = np.array([0.9999, 1.0001])
fnu = np.array([1., 1.])
nu = c / (wav * 1.e-4)

s = m.add_spherical_source()
s.position = 0.5, 0., 0.
s.velocity = -1e8, 0., 0.
s.spectrum = nu[::-1], fnu[::-1]
s.luminosity = 1
s.radius = 0.1
Exemplo n.º 6
0
    def run_thermal_hyperion(self, nphot=1e6, mrw=False, pda=False, \
            niterations=20, percentile=99., absolute=2.0, relative=1.02, \
            max_interactions=1e8, mpi=False, nprocesses=None):
        d = []
        for i in range(len(self.grid.dust)):
            d.append(IsotropicDust( \
                    self.grid.dust[i].nu[::-1].astype(numpy.float64), \
                    self.grid.dust[i].albedo[::-1].astype(numpy.float64), \
                    self.grid.dust[i].kext[::-1].astype(numpy.float64)))

        m = HypModel()
        if (self.grid.coordsystem == "cartesian"):
            m.set_cartesian_grid(self.grid.w1*AU, self.grid.w2*AU, \
                    self.grid.w3*AU)
        elif (self.grid.coordsystem == "cylindrical"):
            m.set_cylindrical_polar_grid(self.grid.w1*AU, self.grid.w3*AU, \
                    self.grid.w2)
        elif (self.grid.coordsystem == "spherical"):
            m.set_spherical_polar_grid(self.grid.w1*AU, self.grid.w2, \
                    self.grid.w3)

        for i in range(len(self.grid.density)):
            if (self.grid.coordsystem == "cartesian"):
                m.add_density_grid(numpy.transpose(self.grid.density[i], \
                        axes=(2,1,0)), d[i])
            if (self.grid.coordsystem == "cylindrical"):
                m.add_density_grid(numpy.transpose(self.grid.density[i], \
                        axes=(1,2,0)), d[i])
            if (self.grid.coordsystem == "spherical"):
                m.add_density_grid(numpy.transpose(self.grid.density[i], \
                        axes=(2,1,0)), d[i])

        sources = []
        for i in range(len(self.grid.stars)):
            sources.append(m.add_spherical_source())
            sources[i].luminosity = self.grid.stars[i].luminosity * L_sun
            sources[i].radius = self.grid.stars[i].radius * R_sun
            sources[i].temperature = self.grid.stars[i].temperature

        m.set_mrw(mrw)
        m.set_pda(pda)
        m.set_max_interactions(max_interactions)
        m.set_n_initial_iterations(niterations)
        m.set_n_photons(initial=nphot, imaging=0)
        m.set_convergence(True, percentile=percentile, absolute=absolute, \
                relative=relative)

        m.write("temp.rtin")

        m.run("temp.rtout", mpi=mpi, n_processes=nprocesses)

        n = ModelOutput("temp.rtout")

        grid = n.get_quantities()

        self.grid.temperature = []
        temperature = grid.quantities['temperature']
        for i in range(len(temperature)):
            if (self.grid.coordsystem == "cartesian"):
                self.grid.temperature.append(numpy.transpose(temperature[i], \
                        axes=(2,1,0)))
            if (self.grid.coordsystem == "cylindrical"):
                self.grid.temperature.append(numpy.transpose(temperature[i], \
                        axes=(2,0,1)))
            if (self.grid.coordsystem == "spherical"):
                self.grid.temperature.append(numpy.transpose(temperature[i], \
                        axes=(2,1,0)))

        os.system("rm temp.rtin temp.rtout")
Exemplo n.º 7
0
    def run_thermal_hyperion(self, nphot=1e6, mrw=False, pda=False, \
            niterations=20, percentile=99., absolute=2.0, relative=1.02, \
            max_interactions=1e8, mpi=False, nprocesses=None):
        d = []
        for i in range(len(self.grid.dust)):
            d.append(IsotropicDust( \
                    self.grid.dust[i].nu[::-1].astype(numpy.float64), \
                    self.grid.dust[i].albedo[::-1].astype(numpy.float64), \
                    self.grid.dust[i].kext[::-1].astype(numpy.float64)))

        m = HypModel()
        if (self.grid.coordsystem == "cartesian"):
            m.set_cartesian_grid(self.grid.w1*AU, self.grid.w2*AU, \
                    self.grid.w3*AU)
        elif (self.grid.coordsystem == "cylindrical"):
            m.set_cylindrical_polar_grid(self.grid.w1*AU, self.grid.w3*AU, \
                    self.grid.w2)
        elif (self.grid.coordsystem == "spherical"):
            m.set_spherical_polar_grid(self.grid.w1*AU, self.grid.w2, \
                    self.grid.w3)

        for i in range(len(self.grid.density)):
            if (self.grid.coordsystem == "cartesian"):
                m.add_density_grid(numpy.transpose(self.grid.density[i], \
                        axes=(2,1,0)), d[i])
            if (self.grid.coordsystem == "cylindrical"):
                m.add_density_grid(numpy.transpose(self.grid.density[i], \
                        axes=(1,2,0)), d[i])
            if (self.grid.coordsystem == "spherical"):
                m.add_density_grid(numpy.transpose(self.grid.density[i], \
                        axes=(2,1,0)), d[i])

        sources = []
        for i in range(len(self.grid.stars)):
            sources.append(m.add_spherical_source())
            sources[i].luminosity = self.grid.stars[i].luminosity * L_sun
            sources[i].radius = self.grid.stars[i].radius * R_sun
            sources[i].temperature = self.grid.stars[i].temperature

        m.set_mrw(mrw)
        m.set_pda(pda)
        m.set_max_interactions(max_interactions)
        m.set_n_initial_iterations(niterations)
        m.set_n_photons(initial=nphot, imaging=0)
        m.set_convergence(True, percentile=percentile, absolute=absolute, \
                relative=relative)

        m.write("temp.rtin")

        m.run("temp.rtout", mpi=mpi, n_processes=nprocesses)

        n = ModelOutput("temp.rtout")

        grid = n.get_quantities()

        self.grid.temperature = []
        temperature = grid.quantities['temperature']
        for i in range(len(temperature)):
            if (self.grid.coordsystem == "cartesian"):
                self.grid.temperature.append(numpy.transpose(temperature[i], \
                        axes=(2,1,0)))
            if (self.grid.coordsystem == "cylindrical"):
                self.grid.temperature.append(numpy.transpose(temperature[i], \
                        axes=(2,0,1)))
            if (self.grid.coordsystem == "spherical"):
                self.grid.temperature.append(numpy.transpose(temperature[i], \
                        axes=(2,1,0)))

        os.system("rm temp.rtin temp.rtout")
# A simple model to check what happens when a source is moving towards dust and
# we observe both the source and the dust. If we observe the source such that
# the dust is directly behind, and the source is moving towards the dust, we
# should see red-shifted emission from the source and blue-shifted scattered
# light emission.

import numpy as np
from hyperion.model import Model
from hyperion.util.constants import c

m = Model()

m.set_cartesian_grid([-1.0, 0, 1], [-1.0, 1.0], [-1.0, 1])

density = np.zeros(m.grid.shape)
density[:, :, 0] = 1.0

m.add_density_grid(density, "kmh_lite.hdf5")

# narrow emission line spectrum at 1 micron
wav = np.array([0.9999, 1.0001])
fnu = np.array([1.0, 1.0])
nu = c / (wav * 1.0e-4)

s = m.add_spherical_source()
s.position = 0.5, 0.0, 0.0
s.velocity = -1e8, 0.0, 0.0
s.spectrum = nu[::-1], fnu[::-1]
s.luminosity = 1
s.radius = 0.1
Exemplo n.º 9
0
    # Global geometry:
    #
    # * slab
    # * system size = 10x10x10 pc
    # * system coordinates (x,y,z min/max) = -5 to +5 pc
    # * slab z extent = -2 to -5 pc
    # * slab xy extend = -5 pc to 5 pc
    # * z optical depth @0.55um in slab = 0.1, 1, 20
    # * optical depth outside slab = 0

    x = np.linspace(-5 * pc, 5 * pc, 100)
    y = np.linspace(-5 * pc, 5 * pc, 100)
    z = np.hstack([np.linspace(-5 * pc, -2 * pc, 100), 5 * pc])

    m.set_cartesian_grid(x, y, z)

    # Grain Properties:

    d = SphericalDust('integrated_hg_scattering.hdf5')
    chi_v = d.optical_properties.interp_chi_wav(0.55)

    # Determine density in slab
    rho0 = tau_v / (3 * pc * chi_v)

    # Set up density grid
    density = np.ones(m.grid.shape) * rho0
    density[-1,:,:] = 0.

    m.add_density_grid(density, d)
Exemplo n.º 10
0
    def __init__(self, par, **kwargs):

        #Set up dust model for Hyperion
        # Initalize the model
        m = Model()
        
        #Set central source position
        m.add_spherical_source(luminosity  = par.get('lsource',1.0*lsun),
                               radius      = par.get('rsource',1.0*rsun),
                               mass        = par.get('msource',1.0*msun),
                               temperature = par.get('tsource',5784.0),
                               position    = par.get('position',(0.0,0.0,0.0))
        
        # Use raytracing to improve s/n of thermal/source emission
        m.set_raytracing(par.get('raytracing',True))
        
        # Use the modified random walk
        m.set_mrw(par.get('modrndwlk',True), gamma=par.get('mrw_gamma',2))

        # Set up spatial grid
        x = np.linspace(-1.5*par.get('rmax',100.*u.au), 1.5*par.get('rmax',100.*u.au), par.get('ngrid',257))
        y = np.linspace(-1.5*par.get('rmax',100.*u.au), 1.5*par.get('rmax',100.*u.au), par.get('ngrid',257))
        z = np.linspace(-1.5*par.get('rmax',100.*u.au), 1.5*par.get('rmax',100.*u.au), par.get('ngrid',257))
        m.set_cartesian_grid(x,y,z)

        print("Spatial grid set up.")

        #Set up density grid
        rho0 = par.get('rho0',1.5e-19)
        alpha_in = par.get('alpha_in',-5.)
        alpha_out = par.get('alpha_out',5.)
        scaleheight= par.get('scaleheight',0.1)
        rmin = par.get('rmin',70.*u.au)
        rmax = par.get('rmax',100.*u.au)
        rmid = (rmax + rmin) / 2
        rr = np.sqrt(m.grid.gx ** 2 + m.grid.gy ** 2 + m.grid.gz ** 2)
        
        #define density grid
        density = np.zeros(m.grid.shape)
        density = rho0 * ( (rr/rmid)**(2.*alpha_in) + (rr/rmid)**(2.*alpha_out) )**(-0.5) * np.exp(-((abs(m.grid.gz)/rr)**2/scaleheight**2)/2.0)
        m.add_density_grid(density, d)

        print("Density grid set up.")
        
        # Set up SED for 10 viewing angles
        sed = m.add_peeled_images(sed=par.get('api_sed',True), image=par.get('api_img',False))
        sed.set_viewing_angles(np.linspace(0., 90., 10), np.repeat(45., 10))
        sed.set_wavelength_range(par.get('nl',101), par.get('lmin',0.1), par.get('lmax',1000.))
        sed.set_track_origin('basic')
        
        # Set number of photons
        m.set_n_photons(initial=par.get('nph_initial',1e4), imaging=par.get('nph_imging',1e5),
                        raytracing_sources=par.get('nph_rtsrcs',1e5), raytracing_dust=par.get('nph_rtdust',1e5))
        
        # Set number of temperature iterations
        m.set_n_initial_iterations(par.get('niter',5))
        
        # Write out file
        m.write('HyperionRT_sed.rtin')
        print("Hyperion RT model created.")

    def __call__(self, *args, **kwargs):
        m.run('HyperionRT_sed.rtout', mpi=True,n_processes=6,overwrite=True)
        print("Hyperion RT model executed.")

        m = ModelOutput('HyperionRT_sed.rtout')

        self.modelFlux = sed.value

    def lnprior(self, theta, **kwargs):
        if self.flatprior:
            if (self.lims[0,0] < theta[0] < self.lims[0,1]) and \
               (self.lims[1,0] < theta[1] < self.lims[1,1]) and \
               (self.lims[2,0] < theta[2] < self.lims[2,1]) and \
               (self.lims[3,0] < theta[3] < self.lims[3,1]) and \
                np.sum(10**theta[4:]) <= 1. and np.all(theta[4:] < 0.): 
                return 0
            else:
                return -np.inf
        else:
            raise NotImplementedError()

    def __str__(self, **kwargs):
        raise NotImplementedError()

    def __repr__(self, **kwargs):
        raise NotImplementedError()

    def inputFile(self, **kwargs):
        #Create a dictionary with which to setup and run Hyperion RT models
        #Dust parameters
        par =   {'dust':'"astrosilicate"',
                 'format':2,
                 'size':0.5,
                 'amin':0.5,
                 'amax':1000.,
                 'na':101,
                 'nang':91,
                 'nanx':11,
                 'nchem':1,
                 'gtd':0,
                 'lmin':0.1,
                 'lmax':1000.0,
                 'nl':101,
                 'massfrac':1.0,
                 'rho0':1.5e-19,
                 'optconst':'"silicate_d03.lnk"',
                 'disttype':'power',
                 'q':3.5,
                 #Source parameters
                 'lsource': 1.0*u.lsun,
                 'rsource': 1.0*u.rsun,
                 'msource': 1.0*u.msun,
                 'tsource': 5784.,
                 'position':[0.0,0.0,0.0],
                 #Disc parameters
                 'rmin': 70.*u.au,
                 'rmax': 100.*u.au,
                 'alpha_in': -5.,
                 'alpha_out': 5.,
                 'scaleheight': 0.1,
                 #RT parameters
                 'niter':5,
                 'nph_initial':1e4,
                 'nph_imging':1e5,
                 'nph_rtsrcs':1e5,
                 'nph_rtdust':1e5,
                 #Peel photons to get images
                 'api_sed':True,
                 'api_img':False,
                 }

        return par

#convenience function to plot the SED of the Hyperion RT output
    def plot_sed(par):
        #Set up figure
        import matplotlib.pyplot as plt
        fig = plt.figure()
        ax = fig.add_subplot(1, 1, 1)
        
        #Read in Hyperion model output
        try:
            m = ModelOutput('HyperionRT_sed.rtout')

            #Total SED
            sed = m.get_sed(inclination=0, aperture=-1, distance=par['distance'],
                                    component='total',units='Jy')        
            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=par['distance'],
                                   component='source_emit',units='Jy')
            ax.loglog(sed.wav, sed.val, color='blue')
            # Scattered stellar photons
            sed = m.get_sed(inclination=0, aperture=-1, distance=par['distance'],
                                   component='source_scat',units='Jy')
            ax.loglog(sed.wav, sed.val, color='teal')
            # Direct dust photons
            sed = m.get_sed(inclination=0, aperture=-1, distance=par['distance'],
                                   component='dust_emit',units='Jy')
            ax.loglog(sed.wav, sed.val, color='red')        
            # Scattered dust photons
            sed = m.get_sed(inclination=0, aperture=-1, distance=par['distance'],
                                   component='dust_scat',units='Jy')
            ax.loglog(sed.wav, sed.val, color='orange')

            ax.set_xlabel(r'$\lambda$ [$\mu$m]')
            ax.set_ylabel(r'Flux [Jy]')
            ax.set_xlim(par.get('lmin',0.1), par.get('lmax',1000.))
            ax.set_ylim(1e-6*np.max(sed.value),1.1*np.max(sed.value))
            fig.savefig('HyperionRT_sed_plot_components.png')
            plt.close(fig)

        except IOError:
            print("No Hyperion RT output found, SED not plotted.")

#convenience function to write dust parameter file '<dust>.params' for Hyperion BHDust calculator (separate program)
    def write_bhmie_file(par):
        f=open(par.get('dust','astrosilicate')+'.params','w')
        f.write('"'+par['dust']+'_'+str(par['size'])+'"'+'\n')
        f.write(str(par['format'])+'\n')
        f.write(str(par['amin'])+'\n')
        f.write(str(par['amax'])+'\n')
        f.write(str(par['na'])+'\n')
        f.write(str(par['nang'])+'\n')
        f.write(str(par['nanx'])+'\n')
        f.write(str(par['nchem'])+'\n')
        f.write(str(par['gtd'])+'\n')
        f.write(str(par['lmin'])+' '+str(par['lmax'])+' '+str(par['nl'])+'\n')
        f.write(''+'\n')
        f.write(str(par['massfrac'])+'\n')
        f.write(str(par['rho0'])+'\n')
        f.write(str(par['optconst'])+'\n')
        f.write(str(par['disttype'])+'\n')
        f.write(str(par['amin'])+' '+str(par['amax'])+' '+str(par['q'])+'\n')
        f.close()

        print("BHMie dust input file created.")

        import subprocess
        subprocess.run(['bhmie',param_file])

        print("BHMie dust output file created")