示例#1
0
 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)
示例#2
0
 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)
示例#3
0
 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)
示例#4
0
 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)
示例#5
0
 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)
示例#6
0
 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)
示例#7
0
 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)
示例#8
0
    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