Пример #1
0
def plot_SivsHI(mets=0.05):
    """
        Plot the SiII fraction as a function of density, for some metallicity.
        Mets is an array, metallicity as a fraction of solar.
    """
    if np.size(mets) == 1:
        mets = np.array([mets,])
    tab = cc.CloudyTable(3)

    #The hydrogen density in atoms/cm^3
    dens = np.logspace(-5,2,100)

    #Roughly mean DLA metallicity

    tabHI = cg.RahmatiRT(3, 0.71)

    tempHI = 1e4*np.ones_like(dens)
    fracHI = tabHI.neutral_fraction(dens,tempHI)
    plt.semilogx(dens, fracHI, color="red",ls="--")

    ls = [":","-","-."]
    for met in mets:
        metSi = tab.get_solar("Si")*met*np.ones_like(dens)
        fracSi = tab.ion("Si",2,metSi,dens)
        plt.semilogx(dens, fracSi, color="green",ls=ls.pop())

    plt.xlabel(r"$\rho_\mathrm{H}\; (\mathrm{amu}/\mathrm{cm}^3$)")
    plt.ylabel(r"$\mathrm{m}_\mathrm{SiII} / \mathrm{m}_\mathrm{Si}$")
    plt.show()
    save_figure(path.join(outdir,"Si_fracs"))
Пример #2
0
 def __init__(self, num, base):
     """Plot various things with the cold gas fraction"""
     ff = hdfsim.get_file(num, base, 0)
     self.redshift = ff["Header"].attrs["Redshift"]
     self.box = ff["Header"].attrs["BoxSize"]
     self.hubble = ff["Header"].attrs["HubbleParam"]
     ff.close()
     self.gas = cold_gas.RahmatiRT(self.redshift, self.hubble)
     #self.yaj=cold_gas.YajimaRT(self.redshift, self.hubble)
     self.num = num
     self.base = base
Пример #3
0
def setup_test(molec, sim):
    """Setup the test case with a simulation"""
    name = myname.get_name(sim)

    f = hdfsim.get_file(3, name, 0)

    redshift = f["Header"].attrs["Redshift"]
    hubble = f["Header"].attrs["HubbleParam"]
    bar = f["PartType0"]

    cold = cold_gas.RahmatiRT(redshift, hubble, molec=molec)

    return (cold, bar)
Пример #4
0
 def set_nHI_grid(self, gas=False, start=0):
     """Set up the grid around each halo where the HI is calculated.
     """
     star=cold_gas.RahmatiRT(self.redshift, self.hubble, molec=self.molec)
     self.cloudy_table = convert_cloudy.CloudyTable(self.redshift)
     self.once=True
     #Now grid the HI for each halo
     files = hdfsim.get_all_files(self.snapnum, self.snap_dir)
     #Larger numbers seem to be towards the beginning
     files.reverse()
     end = np.min([np.size(files),self.end])
     for xx in xrange(start, end):
         ff = files[xx]
         f = h5py.File(ff,"r")
         print "Starting file ",ff
         bar=f["PartType0"]
         ipos=np.array(bar["Coordinates"])
         #Get HI mass in internal units
         mass=np.array(bar["Masses"])
         #Carbon mass fraction
         den = star.get_code_rhoH(bar)
         temp = star.get_temp(bar)
         mass_frac = np.array(bar["GFM_Metals"][:,2])
         #Floor on the mass fraction of the metal
         ind = np.where(mass_frac > 1e-10)
         mass = mass[ind]*mass_frac[ind]
         #High densities will have no CIV anyway.
         den[np.where(den > 1e4)] = 9999.
         den[np.where(den < 1e-7)] = 1.01e-7
         temp[np.where(temp > 3e8)] = 3e8
         temp[np.where(temp < 1e3)] = 1e3
         mass *= self.cloudy_table.ion("C", self.ion, den[ind], temp[ind])
         smooth = hsml.get_smooth_length(bar)[ind]
         ipos = ipos[ind,:][0]
         [self.sub_gridize_single_file(ii,ipos,smooth,mass,self.sub_nHI_grid) for ii in xrange(0,self.nhalo)]
         f.close()
         #Explicitly delete some things.
         del ipos
         del mass
         del smooth
     #Deal with zeros: 0.1 will not even register for things at 1e17.
     #Also fix the units:
     #we calculated things in internal gadget /cell and we want atoms/cm^2
     #So the conversion is mass/(cm/cell)^2
     for ii in xrange(0,self.nhalo):
         massg=self.UnitMass_in_g/self.hubble/(self.protonmass*12.011)
         epsilon=2.*self.sub_radii[ii]/(self.ngrid[ii])*self.UnitLength_in_cm/self.hubble/(1+self.redshift)
         self.sub_nHI_grid[ii]*=(massg/epsilon**2)
         self.sub_nHI_grid[ii]+=0.1
         np.log10(self.sub_nHI_grid[ii],self.sub_nHI_grid[ii])
     return
Пример #5
0
 def set_nHI_grid(self):
     """Set up the grid around each halo where the velocity HI is calculated.
     """
     star=cold_gas.RahmatiRT(self.redshift, self.hubble)
     self.once=True
     #This is the real HI grid
     nHI_grid=np.array([np.zeros([self.ngrid[i],self.ngrid[i]]) for i in xrange(0,self.nhalo)])
     #Now grid the HI for each halo
     for fnum in xrange(0,500):
         try:
             f=hdfsim.get_file(self.snapnum,self.snap_dir,fnum)
         except IOError:
             break
         print "Starting file ",fnum
         bar=f["PartType0"]
         ipos=np.array(bar["Coordinates"],dtype=np.float64)
         smooth = hsml.get_smooth_length(bar)
         # Velocity in cm/s
         vel = np.array(bar["Velocities"],dtype=np.float64)*self.UnitVelocity_in_cm_per_s
         #We will weight by neutral mass per cell
         irhoH0 = star.get_reproc_rhoHI(bar)
         irho=np.array(bar["Density"],dtype=np.float64)*(self.UnitMass_in_g/self.UnitLength_in_cm**3)*self.hubble**2
         #HI * Cell Mass, internal units
         mass = np.array(bar["Masses"],dtype=np.float64)*irhoH0/irho
         f.close()
         #Perform the grid interpolation
         #sub_gas_grid is x velocity
         #sub_nHI_grid is y velocity
         [self.sub_gridize_single_file(ii,ipos,smooth,vel[:,1]*mass,self.sub_gas_grid,vel[:,2]*mass,self.sub_nHI_grid,mass) for ii in xrange(0,self.nhalo)]
         #Find the HI density also, so that we can discard
         #velocities in cells that are not DLAs.
         [self.sub_gridize_single_file(ii,ipos,smooth,irhoH0,nHI_grid,np.zeros(np.size(irhoH0)),nHI_grid) for ii in xrange(0,self.nhalo)]
         #Explicitly delete some things.
         del ipos
         del irhoH0
         del irho
         del smooth
         del mass
         del vel
     #No /= in list comprehensions...  :|
     #Average over z
     for i in xrange(0,self.nhalo):
         self.sub_gas_grid[i]/=self.sub_radii[i]
         self.sub_nHI_grid[i]/=self.sub_radii[i]
         ind = np.where(nHI_grid[i] < 10**20.3)
         self.sub_nHI_grid[i][ind] = 0
         self.sub_gas_grid[i][ind] = 0
     return
Пример #6
0
 def _get_secondary_array(self, ind, bar, elem="", ion=-1):
     """Get the array whose HI weighted amount we want to compute. Throws ValueError
     if key is not a desired species. Note this saves the total projected mass of each species in
     atoms of that species / cm ^2. If you want the total mass in the species, multiply by its atomic mass."""
     if elem == "met":
         met = np.array(bar["GFM_Metallicity"])[ind]
     else:
         nelem = self.species.index(elem)
         met = np.array(bar["GFM_Metals"][:,nelem])[ind]
         #What is saved is the column density in amu, we want the column density,
         #which is in atoms. So there is a factor of mass.
         met /= self.amasses[elem]
         if ion != -1:
             star=cold_gas.RahmatiRT(self.redshift, self.hubble)
             den=star.get_code_rhoH(bar)
             temp = star.get_temp(bar)
             temp = temp[ind]
             den = den[ind]
             met *= self.cloudy_table.ion(elem, ion, den, temp)
     met[np.where(met <=0)] = 1e-50
     return met
Пример #7
0
def plot_SivsHI(temp=3e4, ss_corr=True, elem="Si", ion=2):
    """
        Plot the SiII fraction as a function of density, for some temperature.
        temp is an array, in K.
    """
    if np.size(temp) == 1:
        temp = np.array([
            temp,
        ])
    tab = get_cloudy_table(ss_corr)
    #The hydrogen density in atoms/cm^3
    dens = np.logspace(-5, 0, 100)

    #Roughly mean DLA metallicity

    tabHI = cg.RahmatiRT(3, 0.71)

    fracHI = tabHI.neutral_fraction(dens, temp[0])
    plt.semilogx(dens, fracHI, color="red", ls="--", label="HI/H")

    ls = [":", "-", "-."]
    for tt in temp:
        ttSi = tt * np.ones_like(dens)
        fracSi = tab.ion(elem, ion, dens, ttSi)
        plt.semilogx(dens,
                     fracSi,
                     color="green",
                     ls=ls.pop(),
                     label=r"$" + str(int(tt / 1e4)) + r"\times 10^4$ K")

    plt.xlabel(r"$\rho_\mathrm{H}$ (cm$^{-3}$)")
    plt.ylabel(r"$\mathrm{m}_\mathrm{" + elem + romanise_num(ion) +
               r"} / \mathrm{m}_\mathrm{" + elem + r"}$")
    plt.ylim(0, 1)
    plt.legend(loc=2)
    plt.show()
    save_plot(elem, ion, suffix="fracs", ss_corr=ss_corr)
    plt.clf()
Пример #8
0
    def set_zdir_grid(self, dlaind, gas=False, key="zpos", ion=-1):
        """Set up the grid around each halo where the HI is calculated.
        """
        star = cold_gas.RahmatiRT(self.redshift, self.hubble, molec=self.molec)
        self.once = True
        #Now grid the HI for each halo
        files = hdfsim.get_all_files(self.snapnum, self.snap_dir)
        #Larger numbers seem to be towards the beginning
        files.reverse()
        self.xslab = np.zeros_like(dlaind[0], dtype=np.float64)
        try:
            start = self.load_fast_tmp(self.start, key)
        except IOError:
            start = self.start
        end = np.min([np.size(files), self.end])
        for xx in xrange(start, end):
            ff = files[xx]
            f = h5py.File(ff, "r")
            print "Starting file ", ff
            bar = f["PartType0"]
            ipos = np.array(bar["Coordinates"])
            #Get HI mass in internal units
            mass = np.array(bar["Masses"])
            if not gas:
                #Hydrogen mass fraction
                try:
                    mass *= np.array(bar["GFM_Metals"][:, 0])
                except KeyError:
                    mass *= self.hy_mass
            nhi = star.get_reproc_HI(bar)
            ind = np.where(nhi > 1.e-3)
            ipos = ipos[ind, :][0]
            mass = mass[ind]
            #Get x * m for the weighted z direction
            if not gas:
                mass *= nhi[ind]
            if key == "zpos":
                mass *= ipos[:, 0]
            elif key != "":
                mass *= self._get_secondary_array(ind, bar, key, ion)
            smooth = hsml.get_smooth_length(bar)[ind]
            for slab in xrange(self.nhalo):
                ind = np.where(dlaind[0] == slab)
                self.xslab[ind] += self.sub_list_grid_file(
                    slab, ipos, smooth, mass, dlaind[1][ind], dlaind[2][ind])

            f.close()
            #Explicitly delete some things.
            del ipos
            del mass
            del smooth
            self.save_fast_tmp(start, key)

        #Fix the units:
        #we calculated things in internal gadget /cell and we want atoms/cm^2
        #So the conversion is mass/(cm/cell)^2
        massg = self.UnitMass_in_g / self.hubble / self.protonmass
        epsilon = 2. * self.sub_radii[0] / (
            self.ngrid[0]) * self.UnitLength_in_cm / self.hubble / (
                1 + self.redshift)
        self.xslab *= (massg / epsilon**2)
        return self.xslab
Пример #9
0
    def calc_grid(self, data_dict, kernel_type='SPH'):
        m = data_dict['m']
        pos = data_dict['pos']
        metals = data_dict['metals']
        rho = data_dict['rho']
        rho_Hatoms = data_dict['rho_Hatoms']
        u = data_dict['u']
        nelec = data_dict['nelec']
        hsml = data_dict['hsml']
        T = data_dict['T']
        neut_frac = data_dict['neut_frac']
        grp_id = data_dict['grp_id']
        grp_pos = data_dict['grp_pos']

        r = AU.PhysicalPosition(
            np.sqrt(pos[:, 0]**2. + pos[:, 1]**2. + pos[:, 2]**2.),
            self.redshift)

        if self.verbose: print "# of particles to fieldize over: ", np.size(m)

        grid_dict = {}
        for ss in xrange(self.n_species):
            elem = self.elem_list[ss]
            ion = self.ion_list[ss]
            if self.verbose:
                print "Species: {}".format(elem + str(ion))
                print "Cloudy: {}".format(self.cloudy_type)

            # For neutral hydrogen, use Rahmati fitting formula to compute HI fraction
            if elem == "H" and ion == 1:
                H_massfrac = metals[:, 0]
                star = cold_gas.RahmatiRT(self.redshift, self.hubble)
                fake_bar = {
                    'Density': rho,
                    'NeutralHydrogenAbundance': neut_frac
                }
                new_neut_frac = star.get_reproc_HI(fake_bar)
                species_mass = m * H_massfrac * new_neut_frac

            # Otherwise, use cloudy to compute ion fraction
            else:
                elem_massfrac = metals[:, AU.elem_lookup(elem)]

                if self.cloudy_type == "ion_out_fancy_atten":
                    ion_frac = self.tab.ion(elem, ion, rho_Hatoms, T)
                elif self.cloudy_type == "UVB_sf_xrays_ext":

                    if self.kwargs.has_key('multiple_sources') and self.kwargs[
                            'multiple_sources'] == True:
                        # Count # of subhalos for this group:
                        sub_ids = self.sub_id_dict[grp_id]
                        grp_firstsubid = self.grp_firstsub[grp_id]
                        n_sources = np.size(sub_ids)

                        if n_sources == 0:
                            raise ValueError(
                                "No subhalos for group {}!  ERROR".format(
                                    grp_id))
                        elif n_sources == 1:
                            beta = self.sub_SFR[grp_firstsubid] / r**2.
                        else:
                            # loop over all sources; for each source, get its position, SFR, and stellar mass
                            beta = np.zeros_like(r)
                            # beta_arr = np.zeros([n_sources,np.size(r)])
                            for sub_id in sub_ids:
                                sub_SFR = self.sub_SFR[sub_id]
                                sub_SM = self.sub_SM[sub_id]
                                sub_pos = self.sub_pos[sub_id]

                                if sub_SFR == 0: pass
                                else:
                                    # Put subhalo position in frame where group center is at origin
                                    subpos_cent = self._fix_pos(
                                        grp_pos, np.array([sub_pos]), self.box)
                                    subpos_cent = subpos_cent[0]
                                    # Then calculate distance from each cell to the subhalo position
                                    rs = AU.PhysicalPosition(np.sqrt(\
                                    (pos[:,0]-subpos_cent[0])**2.+\
                                    (pos[:,1]-subpos_cent[1])**2.+\
                                    (pos[:,2]-subpos_cent[2])**2.)\
                                    ,self.redshift)

                                    # Sanity check:
                                    if np.sum(rs > self.box / 2.) > 0:
                                        raise ValueError("Radius error!")

                                    beta += sub_SFR / rs**2.

                    else:
                        beta = self.gal_SFR[grp_id] / r**2.

                    if self.verbose:
                        print "beta {}".format(beta)
                    # Given beta for each cell (radiation that each cell sees from young stellar pops), calculate
                    # ionization states
                    ion_frac = tab.ion(elem, ion, rho_Hatoms, T, beta=beta)

                # Given element mass fraction and ion fraction within that element, we can calculate the species mass in each cell:
                species_mass = m * elem_massfrac * ion_frac

            grid = np.zeros([self.ngrid, self.ngrid])
            self.sub_gridize_single_halo(pos,
                                         hsml,
                                         species_mass,
                                         grid,
                                         kernel_type=kernel_type)

            # Put grid in correct units
            elem_mass_g = AU.elem_atom_mass(elem)
            massg = AU.UnitMass_in_g / self.hubble * (1 / elem_mass_g)
            epsilon = 2. * self.grid_radius / self.ngrid * AU.UnitLength_in_cm / self.hubble / (
                1 + self.redshift)
            grid *= (massg / epsilon**2)
            grid += 0.1
            np.log10(grid, grid)

            grid_dict[elem + str(ion)] = np.copy(grid)

        return grid_dict