def _get_cloudy_table(red, cdir=None): """Get the cloudy table if we didn't already""" #Generate cloudy tables if cdir != None: return convert_cloudy.CloudyTable(red, cdir) else: return convert_cloudy.CloudyTable(red)
def get_cloudy_table(ss_corr=True, redshift=3): """ Helper function to load a table. If ss_corr == True, attenuate the UVB with a self-shielding correction which accounts for the frequency dependence of the hydrogen cross-section. """ if ss_corr: tab = cc.CloudyTable(redshift, "ion_out_photo_atten") else: tab = cc.CloudyTable(redshift, "ion_out_no_atten") return tab
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 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 __init__(self,snap_dir,snapnum,elem,ion,minpart=400,reload_file=False,savefile=None): self.elem=elem self.ion=ion self.species = ['H', 'He', 'C', 'N', 'O', 'Ne', 'Mg', 'Si', 'Fe'] self.minpart=minpart self.snapnum=snapnum self.snap_dir=snap_dir self.set_units() if savefile==None: self.savefile=path.join(snap_dir,"snapdir_"+str(snapnum).rjust(3,'0'),"halomet_grid.hdf5") else: self.savefile = savefile try: if reload_file: raise KeyError("reloading") #First try to load from a file self.load_savefile(self.savefile) except (IOError,KeyError): self.load_header() self.load_halos(minpart) #Generate cloudy tables self.cloudy_table = convert_cloudy.CloudyTable(self.redshift) # Conversion factors from internal units rscale = self.UnitLength_in_cm/(1+self.redshift)/self.hubble # convert length to cm mscale = self.UnitMass_in_g/self.hubble # convert mass to g self.dscale = mscale / rscale **3 # Convert density to g / cm^3 escale = 1.0e6 # convert energy/unit mass to J kg^-1 #convert U (J/kg) to T (K) : U = N k T / (γ - 1) #T = U (γ-1) μ m_P / k_B #where k_B is the Boltzmann constant #γ is 5/3, the perfect gas constant #m_P is the proton mass #μ is 1 / (mean no. molecules per unit atomic weight) calculated in loop. boltzmann = 1.3806504e-23 self.tscale = ((5./3.-1.0) * 1e-3*self.protonmass * escale ) / boltzmann #Otherwise regenerate from the raw data self.sub_nHI_grid=np.array([np.zeros([self.ngrid[i],self.ngrid[i]]) for i in xrange(0,self.nhalo)]) self.set_nHI_grid() return
def __init__(self,snap_dir,snapnum,nslice=1,savefile=None, start=0, end=3000, ngrid=16384, cdir=None): bi.BoxHI.__init__(self, snap_dir, snapnum, nslice, False, savefile, False,start=start, end=end,ngrid=ngrid) if cdir != None: self.cloudy_table = convert_cloudy.CloudyTable(self.redshift, cdir) else: self.cloudy_table = convert_cloudy.CloudyTable(self.redshift)
def __init__(self,run=None,snap_base=None,CGMsnap_base=None,save_base=None,res=None,snapnum=None,grp_ids=None,\ grid_radius_pkpc=None,elem_list=None,ion_list=None,cloudy_type=None,cloudy_dir=None,\ verbose=False,**kwargs): self.run = run self.snap_base = snap_base self.CGMsnap_base = CGMsnap_base self.save_base = save_base self.res = res self.snapnum = snapnum # self.group_min_mass = group_min_mass self.grid_radius_pkpc = grid_radius_pkpc self.elem_list = elem_list self.ion_list = ion_list self.cloudy_type = cloudy_type self.cloudy_dir = cloudy_dir self.kwargs = kwargs self.grp_ids = grp_ids self.verbose = verbose # Or hardcode values: # self.run = None # self.snap_base = None # self.CGMsnap_base = '/n/home04/jsuresh/data1/Projects/Feedback_and_CGM/CGM_new/data/CGM_snaps/' # self.save_base = '/n/home04/jsuresh/data1/Projects/Feedback_and_CGM/CGM_new/data/grids/' # self.res = None #Future: get this from the simulation # self.snapnum = None # # self.group_min_mass = None # self.grid_radius_pkpc = None # self.elem_list = ["C","C"] # self.ion_list = [-1,4] # self.cloudy = "UVB_sf_xrays_ext" # self.cloudy_dir = '/n/home04/jsuresh/scratch1/Cloudy_test/UVB_sf_xrays_ext/' # Here's where the magic happens comm = MPI.COMM_WORLD rank = comm.Get_rank() size = comm.Get_size() if self.verbose: print "my rank = {}".format(rank) print "my size = {}".format(size) #print "done with MPI comm/rank/size initialization!" # Create necessary folder if it does not exist: if rank == 0: grid_dir = self.save_base + "{}/s{}/".format(self.run, snapnum) if not os.path.isdir(grid_dir): if self.verbose: print "Creating {}".format(grid_dir) os.mkdir(grid_dir) # Load header information from snapshot: self.load_header() else: self.redshift = None self.hubble = None self.box = None # Broadcast necessary data from root process to other processes self.redshift = comm.bcast(self.redshift, root=0) self.hubble = comm.bcast(self.hubble, root=0) self.box = comm.bcast(self.box, root=0) # Other set-up self.grid_radius = AU.CodePosition(self.grid_radius_pkpc, self.redshift, hubble=self.hubble) self.npart = self.res**3. self.ngrid = int( np.ceil(40 * self.npart**(1. / 3) / self.box * 2 * self.grid_radius)) tab = ccl.CloudyTable(self.redshift, directory=cloudy_dir) self.n_species = len(self.elem_list) self.n_selected_groups = np.size(self.grp_ids) if self.cloudy_type == "UVB_sf_xrays_ext": if not kwargs.has_key(multiple_sources): try: self.gal_SFR = kwargs['gal_SFR'] except: raise KeyError( "Need gal_SFR to be passed in for cloudy type {}". format(self.cloudy_type)) if kwargs.has_key( multiple_sources) and kwargs['multiple_sources'] == True: try: self.sub_id_dict = kwargs[ 'sub_id_dict'] # Dictionary which, for each group, has list of corresponding subhalo IDs self.sub_pos = kwargs['sub_pos'] self.sub_SM = kwargs['sub_SM'] self.sub_SFR = kwargs['sub_SFR'] self.grp_firstsub = kwargs['grp_firstsub'] except: raise KeyError( "Missing some of the subhalo data which are necessary to implement multiple sources." ) for i in np.arange(self.n_selected_groups): if (i % size == rank): if self.verbose: print "Projecting i / task:", i, rank grp_id = self.grp_ids[i] # Work on this group if CGM snapshot exists and grid file does not already exist: CGMsnap_file_path = self.CGMsnap_base + "{}/s{}/{}.hdf5".format( self.run, self.snapnum, str(int(grp_id)).zfill(5)) save_path = self.save_base + "{}/s{}/{}.hdf5".format( self.run, snapnum, str(int(grp_id)).zfill(5)) if not os.path.isfile(CGMsnap_file_path): if self.verbose: print "File {} does not exist! Skipping...".format( CGMsnap_file_path) elif os.path.isfile(save_path): if self.verbose: print "File {} already exists! Skipping...".format( save_path) else: if self.verbose: print "Working on {}".format(save_path) data_dict = self.load_CGM_file(grp_id, CGMsnap_file_path, center_positions=True, radial_cut=True) grid_dict = self.calc_grid(data_dict, kernel_type='SPH') self.save_grid(grp_id, grid_dict, save_path)