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"))
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
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)
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
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
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
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()
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
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