def get_units(self): """Get the base scales for the unit system.""" length = self.get_header_attr("UnitLength_in_cm") mass = self.get_header_attr("UnitMass_in_g") vel = self.get_header_attr("UnitVelocity_in_cm_per_s") units = unitsystem.UnitSystem(UnitLength_in_cm=length, UnitMass_in_g=mass, UnitVelocity_in_cm_per_s=vel) return units
def __init__(self, redshift, absnap, hubble=0.71, fbar=0.17, units=None, sf_neutral=True): if units is not None: self.units = units else: self.units = unitsystem.UnitSystem() self.absnap = absnap self.f_bar = fbar self.redshift = redshift self.sf_neutral = sf_neutral #Interpolate for opacity and gamma_UVB #Opacities for the FG09 UVB from Rahmati 2012. #IMPORTANT: The values given for z > 5 are calculated by fitting a power law and extrapolating. #Gray power law was: -1.12e-19*(zz-3.5)+2.1e-18 fit to z > 2. #gamma_UVB was: -8.66e-14*(zz-3.5)+4.84e-13 #This is clearly wrong, but this model is equally a poor choice at these redshifts anyway. gray_opac = [ 2.59e-18, 2.37e-18, 2.27e-18, 2.15e-18, 2.02e-18, 1.94e-18, 1.82e-18, 1.71e-18, 1.60e-18 ] gamma_UVB = [ 3.99e-14, 3.03e-13, 6e-13, 5.53e-13, 4.31e-13, 3.52e-13, 2.678e-13, 1.81e-13, 9.43e-14 ] zz = [0, 1, 2, 3, 4, 5, 6, 7, 8] self.redshift_coverage = True if redshift > zz[-1]: self.redshift_coverage = False print("Warning: no self-shielding at z=", redshift) else: gamma_inter = intp.interp1d(zz, gamma_UVB) gray_inter = intp.interp1d(zz, gray_opac) self.gray_opac = gray_inter(redshift) self.gamma_UVB = gamma_inter(redshift) #self.hy_mass = 0.76 # Hydrogen massfrac self.gamma = 5. / 3 #Boltzmann constant (cgs) self.boltzmann = 1.38066e-16 self.hubble = hubble #Physical density threshold for star formation in H atoms / cm^3 self.PhysDensThresh = self._get_rho_thresh(hubble)
def testAbsDist(): """Check absorption distance computation""" units = unitsystem.UnitSystem() assert units.absorption_distance(25000, 3) == 0.13377926628219666 assert units.absorption_distance(25000, 2) == 0.07525083728373562 assert units.absorption_distance(25000, 3) / units.absorption_distance(12500, 3) == 2.
def testRhoCrit(): """Critical density at z=0""" units = unitsystem.UnitSystem() assert units.rho_crit(0.7) == 9.204285430050004e-30 assert units.rho_crit(1.0) == 1.8784255979693885e-29
def __init__(self,num, base,cofm, axis, res=1., cdir=None, savefile="spectra.hdf5", savedir=None, reload_file=False, snr = 0., spec_res = 8,load_halo=False, units=None, sf_neutral=True,quiet=False): #Present for compatibility. Functionality moved to HaloAssignedSpectra _= load_halo self.num = num self.base = base #Create the unit system if units != None: self.units = units else: self.units = unitsystem.UnitSystem() #Empty dictionary to add results to self.tau_obs = {} self.tau = {} self.sfr = {} self.vel_widths = {} self.absorber_width = {} self.colden = {} self.velocity = {} self.temp = {} #A cache of the indices of particles near sightlines. self.part_ind = {} #This variable should be set to true once the sightlines are fixed, and the cache can be used. self.cofm_final = False self.num_important = {} self.discarded=0 self.npart=0 #If greater than zero, will add noise to spectra when they are loaded. self.snr = snr self.spec_res = spec_res self.cdir = cdir #Minimum length of spectra within which to look at metal absorption (in km/s) self.minwidth = 500. try: self.snapshot_set = absn.AbstractSnapshotFactory(num, base) except IOError: pass if savedir is None: #Use snapdir if exists, otherwise use SPEC_ savedir = path.join(base,"snapdir_"+str(num).rjust(3,'0')) #Make sure savedir exists. if not path.exists(savedir): savedir = path.join(base,"SPECTRA_"+str(num).rjust(3,'0')) self.savefile = path.join(savedir,savefile) #Snapshot data if reload_file: if not quiet: print("Reloading from snapshot (will save to: ",self.savefile," )") #Make sure the obvious syntax for a single sightline works if np.shape(cofm) == (3,): cofm = np.array([cofm,]) self.cofm = cofm.astype(np.float64) if np.shape(axis) == (): axis = np.array([axis]) self.axis = axis.astype(np.int32) if cofm is None or axis is None: raise RuntimeError("None was passed for cofm or axis. If you are trying to load from a savefile, use reload_file=False.") try: self.npart=self.snapshot_set.get_npart() #If we got here without a snapshot_set, we really have an IOError except AttributeError: raise IOError("Unable to load snapshot ",num, base) self.box = self.snapshot_set.get_header_attr("BoxSize") self.atime = self.snapshot_set.get_header_attr("Time") self.red = 1/self.atime - 1. self.hubble = self.snapshot_set.get_header_attr("HubbleParam") self.OmegaM = self.snapshot_set.get_header_attr("Omega0") self.OmegaLambda = self.snapshot_set.get_header_attr("OmegaLambda") #Calculate omega_baryon (approximately only for HDF5) self.omegab = self.snapshot_set.get_omega_baryon() #Get the unit system. try: self.units = self.snapshot_set.get_units() except KeyError: if not quiet: print('No units found. Using kpc/kms/10^10Msun by default') else: self.load_savefile(self.savefile) # Conversion factors from internal units self.rscale = (self.units.UnitLength_in_cm*self.atime)/self.hubble # convert length to physical cm # Calculate the length scales to be used in the box: Hz in km/s/Mpc Hz = 100.0*self.hubble * np.sqrt(self.OmegaM/self.atime**3 + self.OmegaLambda) #Convert comoving internal units to physical km/s. #Numerical constant is 1 Mpc in cm. self.velfac = self.rscale * Hz / 3.085678e24 self.vmax = self.box * self.velfac # box size (physical kms^-1) self.NumLos = np.size(self.axis) try: # velocity bin size (kms^-1) self.dvbin = self.vmax / (1.*self.nbins) except AttributeError: #This will occur if we are not loading from a savefile self.dvbin = res # velocity bin size (kms^-1) #Number of bins to achieve the required resolution self.nbins = int(self.vmax / self.dvbin) #Species we can use: Z is total metallicity self.species = ['H', 'He', 'C', 'N', 'O', 'Ne', 'Mg', 'Si', 'Fe', 'Z'] #Solar abundances from Asplund 2009 / Grevasse 2010 (which is used in Cloudy 13, Hazy Table 7.4). self.solar = {"H":1, "He":0.0851, "C":2.69e-4,"N":6.76e-5,"O":4.9e-4,"Ne":8.51e-5,"Mg":3.98e-5,"Si":3.24e-5,"Fe":3.16e-5} # Total solar metallicity is from Asplund 2009 0909.0948 # Note the solar metallicity is the mass fraction of metals # divided by the mass fraction of hydrogen self.solarz = 0.0134/0.7381 #Line data self.lines = line_data.LineData() #Load the class for computing gas properties such as temperature from the raw simulation. try: self.gasprop=gas_properties.GasProperties(redshift = self.red, absnap=self.snapshot_set, hubble=self.hubble, units=self.units, sf_neutral=sf_neutral) except AttributeError: #Occurs if we didn't load a snapshot pass if not quiet: print(self.NumLos, " sightlines. resolution: ", self.dvbin, " z=", self.red)