def test_tau_l_1(self): """ Test tau_l function Equations from Viner, Vallee, and Hughes 1979 """ electron_temp = 10000. # K electron_dens = 150. # cm-3 size = 50. # pc fit_lines = np.array([58.,102.]) deltan = 1. v_turbulent = 15. # km/s use_voigt = True heII_abundance = 0. heIII_abundance = 0. bn = 1. betan = 1. # calculate Doppler velocity (frequency doesn't matter) deltaV_doppler, deltaNu_doppler = utils.doppler_width(electron_temp,v_turbulent,10.) tau_l_answer = np.array([6.69337456e-05,3.57980909e-04]) tau_l_idl = np.array([6.6934236797953418e-05,0.00035798352477698156]) tau_l_check = utils.tau_l(electron_temp,electron_dens,size,fit_lines,deltaV_doppler, deltan=deltan,v_turbulent=v_turbulent, use_voigt=use_voigt,heII_abundance=heII_abundance, heIII_abundance=heIII_abundance,bn=bn,betan=betan) for answer,check in zip(tau_l_answer,tau_l_check): self.assertLess(np.abs(check-answer)/answer,1.e-4) for idl,answer in zip(tau_l_idl,tau_l_answer): self.assertLess(np.abs(idl-answer)/answer,1.e-4)
def test_peak_line_fluxden_1(self): """ Test peak_line_fluxden function Equation 1 from Anantharamaiah+1993 """ electron_temp = 5000. # K electron_dens = 100. # cm-3 HII_region_size = 1 # pc distance = 3. # Mpc omega_HII_region = np.pi * (0.5*HII_region_size/(distance*1.e6))**2. omega_region = 60. # sq arcsec omega_region = omega_region * (np.pi/(180.*60.*60.))**2. # sr fit_lines = np.array([58,102]) rrl_freq = utils.rrl_freq(fit_lines) heII_abundance = 0. heIII_abundance = 0. tau_c = utils.tau_c(electron_temp,electron_dens,HII_region_size, rrl_freq,heII_abundance=heII_abundance,heIII_abundance=heIII_abundance) v_turbulent=15. bn = 1. betan = 1. deltaV_doppler, deltaNu_doppler = utils.doppler_width(electron_temp,v_turbulent,rrl_freq) tau_l_star = utils.tau_l(electron_temp,electron_dens,HII_region_size, fit_lines,deltaV_doppler,deltan=1,v_turbulent=v_turbulent, heII_abundance=heII_abundance,heIII_abundance=heIII_abundance, bn=1.,betan=1.) tau_l = utils.tau_l(electron_temp,electron_dens,HII_region_size, fit_lines,deltaV_doppler,deltan=1,v_turbulent=v_turbulent, heII_abundance=heII_abundance,heIII_abundance=heIII_abundance, bn=bn,betan=betan) background_fluxden = 0. peak_line_fluxden_HII_region_answer = np.array([5.69481083e-34,1.05179646e-34]) # W/m2/Hz peak_line_fluxden_HII_region_idl = np.array([5.6917396965089532e-31,1.0519186812853735e-31])*1.e-3 # W/m2/Hz peak_line_fluxden_background_answer = np.array([0.,0.]) # W/m2/Hz peak_line_fluxden_background_idl = np.array([0.,0.])*1.e-3 # W/m2/Hz peak_line_fluxden_HII_region_check,peak_line_fluxden_background_check = \ utils.peak_line_fluxden(electron_temp,omega_HII_region, omega_region,rrl_freq,tau_c, tau_l_star,tau_l,bn=bn, background_fluxden=background_fluxden) for answer,check in zip(peak_line_fluxden_HII_region_answer,peak_line_fluxden_HII_region_check): self.assertLess(np.abs(check-answer)/answer,1.e-4) for answer,check in zip(peak_line_fluxden_background_answer,peak_line_fluxden_background_check): self.assertEqual(check,answer) for idl,answer in zip(peak_line_fluxden_HII_region_idl,peak_line_fluxden_HII_region_answer): # difference is 0.000539. I think this is a physical constants problem self.assertLess(np.abs(idl-answer)/answer,1.e-3) for idl,answer in zip(peak_line_fluxden_background_idl,peak_line_fluxden_background_answer): self.assertEqual(idl,answer)
def test_doppler_width_2(self): electron_temp = 10000. # K v_turbulent = 15. # km/s freq = np.array([15.,25.,35.]) # GHz deltaV_doppler_answer = 29.552301727587636 # km/s deltaV_doppler_idl = 29.552301 # km/s deltaNu_doppler_answer = np.array([0.00147864,0.0024644,0.00345016]) # GHz deltaNu_doppler_idl = np.array([0.0014786379828836769,0.0024643967399351446,0.0034501553951909293]) # GHz deltaV_doppler_check,deltaNu_doppler_check = utils.doppler_width(electron_temp,v_turbulent,freq) self.assertLess(np.abs(deltaV_doppler_check-deltaV_doppler_answer)/deltaV_doppler_answer,1.e-4) for answer,check in zip(deltaNu_doppler_answer,deltaNu_doppler_check): self.assertLess(np.abs(check-answer)/answer,1.e-4) self.assertLess(np.abs(deltaV_doppler_idl-deltaV_doppler_answer)/deltaV_doppler_answer,1.e-4) for idl,answer in zip(deltaNu_doppler_idl,deltaNu_doppler_answer): self.assertLess(np.abs(idl-answer)/answer,1.e-4)
def test_peak_line_fluxden_2(self): electron_temp = 10000. # K electron_dens = 10. # cm-3 HII_region_size = 100. # pc distance = 3. # Mpc omega_HII_region = np.pi * (0.5*HII_region_size/(distance*1.e6))**2. omega_region = 30. # sq arcsec omega_region = omega_region * (np.pi/(180.*60.*60.))**2. # sr fit_lines = np.array([80.,115]) rrl_freq = utils.rrl_freq(fit_lines) heII_abundance = 0.08 heIII_abundance = 0.01 tau_c = utils.tau_c(electron_temp,electron_dens,HII_region_size, rrl_freq,heII_abundance=heII_abundance,heIII_abundance=heIII_abundance) v_turbulent=0. bn = 0.9 betan = -45. deltaV_doppler, deltaNu_doppler = utils.doppler_width(electron_temp,v_turbulent,rrl_freq) tau_l_star = utils.tau_l(electron_temp,electron_dens,HII_region_size, fit_lines,deltaV_doppler,deltan=1,v_turbulent=v_turbulent, heII_abundance=heII_abundance,heIII_abundance=heIII_abundance, bn=1.,betan=1.) tau_l = utils.tau_l(electron_temp,electron_dens,HII_region_size, fit_lines,deltaV_doppler,deltan=1,v_turbulent=v_turbulent, heII_abundance=heII_abundance,heIII_abundance=heIII_abundance, bn=bn,betan=betan) background_fluxden = 30. * 1.e-29 # W/m2/Hz peak_line_fluxden_HII_region_answer = np.array([7.45601155e-31,2.52914885e-31]) # W/m2/Hz peak_line_fluxden_HII_region_idl = np.array([7.4560553782987313e-28,2.5291638366348540e-28])*1.e-3 # W/m2/Hz peak_line_fluxden_background_answer = np.array([1.46109857e-32,4.31011918e-32]) # W/m2/Hz peak_line_fluxden_background_idl = np.array([1.4605445e-32,4.3102095e-32]) # W/m2/Hz peak_line_fluxden_HII_region_check,peak_line_fluxden_background_check = \ utils.peak_line_fluxden(electron_temp,omega_HII_region, omega_region,rrl_freq,tau_c, tau_l_star,tau_l,bn=bn, background_fluxden=background_fluxden) for answer,check in zip(peak_line_fluxden_HII_region_answer,peak_line_fluxden_HII_region_check): self.assertLess(np.abs(check-answer)/answer,1.e-4) for answer,check in zip(peak_line_fluxden_background_answer,peak_line_fluxden_background_check): self.assertLess(np.abs(check-answer)/answer,1.e-4) for idl,answer in zip(peak_line_fluxden_HII_region_idl,peak_line_fluxden_HII_region_answer): self.assertLess(np.abs(idl-answer)/answer,1.e-4) for idl,answer in zip(peak_line_fluxden_background_idl,peak_line_fluxden_background_answer): # difference is 0.000379. I think this is a physical constants problem self.assertLess(np.abs(idl-answer)/answer,1.e-3)
def test_doppler_width_1(self): """ Test the doppler_width function Equation 13 from Viner, Vallee, and Hughes 1979 """ electron_temp = 5000. # K v_turbulent = 0. # km/s freq = np.array([10.,20.,30.]) # GHz deltaV_doppler_answer = 15.12365432994584 # km/s deltaV_doppler_idl = 15.123654 # km/s deltaNu_doppler_answer = np.array([0.00050447,0.00100894,0.00151341]) # GHz deltaNu_doppler_idl = np.array([0.00050447080209084809,0.0010089416041816962,0.0015134124062725443]) # GHz deltaV_doppler_check,deltaNu_doppler_check = utils.doppler_width(electron_temp,v_turbulent,freq) self.assertLess(np.abs(deltaV_doppler_check-deltaV_doppler_answer)/deltaV_doppler_answer,1.e-4) for answer,check in zip(deltaNu_doppler_answer,deltaNu_doppler_check): self.assertLess(np.abs(check-answer)/answer,1.e-4) self.assertLess(np.abs(deltaV_doppler_idl-deltaV_doppler_answer)/deltaV_doppler_answer,1.e-4) for idl,answer in zip(deltaNu_doppler_idl,deltaNu_doppler_answer): self.assertLess(np.abs(idl-answer)/answer,1.e-4)
def test_tau_l_3(self): electron_temp = 5000. # K electron_dens = 100. # cm-3 size = 100. # pc fit_lines = np.array([65.,115.]) deltan = 1 v_turbulent = 0. # km/s use_voigt = False heII_abundance = 0.08 heIII_abundance = 0.01 bn = 0.9 betan = -45. # calculate Doppler velocity (frequency doesn't matter) deltaV_doppler, deltaNu_doppler = utils.doppler_width(electron_temp,v_turbulent,10.) tau_l_answer = np.array([-0.03408548,-0.18597207]) tau_l_idl = np.array([-0.034085729216465736,-0.18597342453371252]) tau_l_check = utils.tau_l(electron_temp,electron_dens,size,fit_lines,deltaV_doppler, deltan=deltan,v_turbulent=v_turbulent, use_voigt=use_voigt,heII_abundance=heII_abundance, heIII_abundance=heIII_abundance,bn=bn,betan=betan) for answer,check in zip(tau_l_answer,tau_l_check): self.assertLess(np.abs(check-answer)/answer,1.e-4) for idl,answer in zip(tau_l_idl,tau_l_answer): self.assertLess(np.abs(idl-answer)/answer,1.e-4)
def test_tau_l_2(self): electron_temp = 5000. # K electron_dens = 100. # cm-3 size = 100. # pc fit_lines = np.array([65,115]) deltan = 1 v_turbulent = 0. # km/s use_voigt = True heII_abundance = 0.08 heIII_abundance = 0.01 bn = 0.9 betan = -45. # calculate Doppler velocity (frequency doesn't matter) deltaV_doppler, deltaNu_doppler = utils.doppler_width(electron_temp,v_turbulent,10.) tau_l_answer = np.array([-0.03408153,-0.18429481]) tau_l_idl = np.array([-0.034081771945503062,-0.18429615935433580]) tau_l_check = utils.tau_l(electron_temp,electron_dens,size,fit_lines,deltaV_doppler, deltan=deltan,v_turbulent=v_turbulent, use_voigt=use_voigt,heII_abundance=heII_abundance, heIII_abundance=heIII_abundance,bn=bn,betan=betan) for answer,check in zip(tau_l_answer,tau_l_check): self.assertLess(np.abs(check-answer)/answer,1.e-4) for idl,answer in zip(tau_l_idl,tau_l_answer): self.assertLess(np.abs(idl-answer)/answer,1.e-4)
def calc_HII_region_properties(self): """ Calculate physical properties for this HII region model Inputs: None Returns: None """ # # Solid angle of single HII region (sterradians) # self.omega_HII_region = np.pi * (0.5*self.HII_region_size/(self.distance*1.e6))**2. # # Departure coefficients # self.bn,self.betan = generate_departure_coeffs(self.electron_temp,self.electron_dens,self.fit_lines) # # RRL frequency # self.rrl_freq = utils.rrl_freq(self.fit_lines,self.deltan) # # doppler width of a single HII region # self.deltaV_doppler, self.deltaNu_doppler = \ utils.doppler_width(self.electron_temp,self.v_turbulent, self.rrl_freq) # # Continuum optical depth at RRL frequency and continuum frequencies # self.tau_c_rrl = utils.tau_c(self.electron_temp,self.electron_dens, self.HII_region_size,self.rrl_freq, heII_abundance=self.heII_abundance,heIII_abundance=self.heIII_abundance) self.tau_c_cont = utils.tau_c(self.electron_temp,self.electron_dens, self.HII_region_size,self.contdata['freq_GHz'], heII_abundance=self.heII_abundance,heIII_abundance=self.heIII_abundance) # # LTE line opacity # self.tau_l_star = utils.tau_l(self.electron_temp,self.electron_dens, self.HII_region_size,self.fit_lines,self.deltaV_doppler,deltan=self.deltan, v_turbulent=self.v_turbulent,use_voigt=self.use_voigt, heII_abundance=self.heII_abundance,heIII_abundance=self.heIII_abundance, bn=1.,betan=1.) # # non-LTE line opacity # self.tau_l = utils.tau_l(self.electron_temp,self.electron_dens, self.HII_region_size,self.fit_lines,self.deltaV_doppler,deltan=self.deltan, v_turbulent=self.v_turbulent,use_voigt=self.use_voigt, heII_abundance=self.heII_abundance,heIII_abundance=self.heIII_abundance, bn=self.bn,betan=self.betan) # # peak line flux density from a single HII region # self.peak_line_fluxden_HII_region,self.peak_line_fluxden_background = \ utils.peak_line_fluxden(self.electron_temp,self.omega_HII_region, self.omega_region,self.rrl_freq, self.tau_c_rrl,self.tau_l_star,self.tau_l, bn=self.bn,background_fluxden=self.background_fluxden) self.peak_line_fluxden = self.peak_line_fluxden_HII_region + self.peak_line_fluxden_background # # line flux from a single HII region # self.line_flux = \ utils.line_flux(self.peak_line_fluxden,self.deltaNu_doppler) # # minimum number of HII regions # self.min_num_HII_regions = \ utils.min_num_HII_regions(self.linedata['fwhm_kms'][self.n_for_num_linedata_ind], self.deltaV_doppler, self.linedata['omegaB_sr'][self.n_for_num_linedata_ind], self.omega_region) # # number of HII regions; only calculate this if we were not # specified with a number of HII regions # if self.num_HII_regions is None: self.num_HII_regions = \ utils.num_HII_regions(self.linedata['intflux_Wm2'][self.n_for_num_linedata_ind], self.line_flux[self.n_for_num_fit_lines_ind], line_flux_override=self.line_flux_override) # # maximum number of HII regions # check that num_HII_regions is sensible # if math.isnan(self.num_HII_regions): self.max_num_HII_regions = 1.0e10 else: self.max_num_HII_regions = \ utils.max_num_HII_regions(self.region_size, self.HII_region_size, self.num_HII_regions) # # Number of HII regions along LOS # self.num_HII_regions_los = \ utils.num_HII_regions_los(self.num_HII_regions,self.HII_region_size, self.region_size) # # HII region filling factor # self.filling_factor = \ utils.filling_factor(self.num_HII_regions,self.HII_region_size, self.region_size) # # Calculate the thermal flux density # self.thermal_fluxden_cont = \ utils.thermal_fluxden(self.contdata['freq_GHz'],self.electron_temp, self.omega_HII_region,self.omega_region, self.tau_c_cont,self.num_HII_regions,self.num_HII_regions_los) self.thermal_fluxden_rrl = \ utils.thermal_fluxden(self.rrl_freq,self.electron_temp, self.omega_HII_region,self.omega_region, self.tau_c_rrl,self.num_HII_regions,self.num_HII_regions_los) # # Calculate the non-thermal flux density # self.nonthermal_fluxden_cont,self.unatten_nonthermal_fluxden_cont = \ utils.nonthermal_fluxden(self.contdata['S_C_mJy'],self.thermal_fluxden_cont, self.tau_c_cont,self.num_HII_regions_los) # # Calculate nonthermal spectral index and scaling factor # self.nonthermal_spectral_index, self.nonthermal_scaling_factor = \ utils.spectral_info(self.contdata['freq_GHz'], self.unatten_nonthermal_fluxden_cont) # # Calculate the non-thermal flux density using the scaling # factor and spectral index # self.nonthermal_fluxden_rrl,self.unatten_nonthermal_fluxden_rrl = \ utils.nonthermal_fluxden_model(self.nonthermal_spectral_index,self.nonthermal_scaling_factor, self.rrl_freq, self.tau_c_rrl,self.num_HII_regions_los) # # Calculate the mass of ionized gas # self.mass_ion = \ utils.mass_ion(self.num_HII_regions,self.HII_region_size, self.electron_dens) # # Calculate the number of H-ionizing photons per sec # self.num_ion = \ utils.num_ion(self.num_HII_regions,self.HII_region_size, self.electron_dens,self.electron_temp) # # Calculate the star formation rate (SFR) # (Murphy et al. 2011 using Starburst99 code) # self.sfr = 7.29e-54*self.num_ion