Example #1
0
 def test_thermal_fluxden_1(self):
     """
     Test thermal_fluxden function
     Equations 2-4 in Anantharamaiah+1993
     """
     contfreqs = np.array([10,40]) # GHz
     electron_temp = 5000. # K
     electron_dens = 100. # cm-3
     HII_region_size = 1 # pc
     region_size = 1000. # pc
     distance = 3. # Mpc
     omega_HII_region = np.pi * (0.5*HII_region_size/(distance*1.e6))**2.
     omega_region = np.pi * (0.5*region_size/(distance*1.e6))**2.
     heII_abundance = 0.
     heIII_abundance = 0.
     tau_c_cont = utils.tau_c(electron_temp,electron_dens,HII_region_size,contfreqs,
                                    heII_abundance=heII_abundance,heIII_abundance=heIII_abundance)
     num_HII_regions = 100.
     num_HII_regions_los = utils.num_HII_regions_los(num_HII_regions,HII_region_size,region_size)
     thermal_fluxden_answer = np.array([8.53670801e-32,6.95232971e-32]) # W/m2/Hz
     thermal_fluxden_idl = np.array([8.5338193031806409e-29,6.9037639306629900e-29])*1.e-3 # W/m2/Hz        
     thermal_fluxden_check = utils.thermal_fluxden(contfreqs,electron_temp,
                                                        omega_HII_region,omega_region,
                                                        tau_c_cont,num_HII_regions,num_HII_regions_los)
     for answer,check in zip(thermal_fluxden_answer,thermal_fluxden_check):
         self.assertLess(np.abs(check-answer)/answer,1.e-4)
     for idl,answer in zip(thermal_fluxden_idl,thermal_fluxden_answer):
         # difference is 0.000338 and 0.006985. Physical constants?
         self.assertLess(np.abs(idl-answer)/answer,1.e-2)
Example #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)
Example #3
0
 def test_tau_c_2(self):
     electron_temp = 10000. # K
     electron_dens = 10. # cm-3
     size = 1. # pc
     freq_obs = np.array([15.,25.,35.]) # GHz
     heII_abundance = 0.08
     heIII_abundance = 0.01
     tau_c_answer = np.array([1.10201330e-07,3.71637032e-08,1.81179668e-08])
     # N.B. Found bug in AAK IDL code. Missing * on line 164. This is the fixed answer:
     tau_c_idl = np.array([1.1020132913129986e-07,3.7163705904493164e-08,1.8117965318156966e-08])
     tau_c_check = utils.tau_c(electron_temp,electron_dens,size,freq_obs,
                                    heII_abundance=heII_abundance,heIII_abundance=heIII_abundance)
     for answer,check in zip(tau_c_answer,tau_c_check):
         self.assertLess(np.abs(check-answer)/answer,1.e-4)
     for idl,answer in zip(tau_c_idl,tau_c_answer):
         self.assertLess(np.abs(idl-answer)/answer,1.e-4)
Example #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)
Example #5
0
 def test_tau_c_1(self):
     """
     Test tau_c function
     Equations from Viner, Vallee, and Hughes 1979 (eqs. 9,10)
     """
     electron_temp = 5000. # K
     electron_dens = 100. # cm-3
     size = 10. # pc
     freq_obs = np.array([10.,20.,30.]) # GHz
     heII_abundance = 0.
     heIII_abundance = 0.
     tau_c_answer = np.array([6.36817617e-04,1.44428600e-04,6.03490261e-05])
     tau_c_idl = np.array([0.00063682221000715272,0.00014442964131460524,6.0349463698091224e-05])
     tau_c_check = utils.tau_c(electron_temp,electron_dens,size,freq_obs,
                                    heII_abundance=heII_abundance,heIII_abundance=heIII_abundance)
     for answer,check in zip(tau_c_answer,tau_c_check):
         self.assertLess(np.abs(check-answer)/answer,1.e-4)
     for idl,answer in zip(tau_c_idl,tau_c_answer):
         self.assertLess(np.abs(idl-answer)/answer,1.e-4)
Example #6
0
 def test_nonthermal_fluxden_1(self):
     """
     Test nonthermal_fluxden function
     Equations 5 and 6 in Anantharamaiah+1993
     """
     contfreqs = np.array([5.,35.]) # GHz
     contfluxden = np.array([70.,30.]) # mJy
     electron_temp = 5000. # K
     electron_dens = 1.e3 # cm-3
     HII_region_size = 1. # pc
     region_size = 500. # pc
     distance = 3. # Mpc
     omega_HII_region = np.pi * (0.5*HII_region_size/(distance*1.e6))**2.
     omega_region = np.pi * (0.5*region_size/(distance*1.e6))**2.
     heII_abundance = 0.
     heIII_abundance = 0.
     tau_c_cont = utils.tau_c(electron_temp,electron_dens,HII_region_size,contfreqs,
                                    heII_abundance=heII_abundance,heIII_abundance=heIII_abundance)
     num_HII_regions = 1000.
     num_HII_regions_los = utils.num_HII_regions_los(num_HII_regions,HII_region_size,region_size)
     thermal_fluxden = utils.thermal_fluxden(contfreqs,electron_temp,
                                             omega_HII_region,omega_region,
                                             tau_c_cont,num_HII_regions,num_HII_regions_los)
     nonthermal_fluxden_answer = np.array([6.07993533e-28,2.28965594e-28]) # W/m2/Hz
     nonthermal_fluxden_idl = np.array([6.0799355e-28,2.2896558e-28]) # W/m2/Hz
     unatten_nonthermal_fluxden_answer = np.array([6.08026917e-28,2.28965792e-28]) # W/m2/Hz
     unatten_nonthermal_fluxden_idl = np.array([6.0802692e-28,2.2896579e-28]) # W/m2/Hz
     nonthermal_fluxden_check,unatten_nonthermal_fluxden_check = \
       utils.nonthermal_fluxden(contfluxden,thermal_fluxden,tau_c_cont,
                                num_HII_regions_los)
     for answer,check in zip(nonthermal_fluxden_answer,nonthermal_fluxden_check):
         self.assertLess(np.abs(check-answer)/answer,1.e-4)
     for answer,check in zip(unatten_nonthermal_fluxden_answer,unatten_nonthermal_fluxden_check):
         self.assertLess(np.abs(check-answer)/answer,1.e-4)
     for idl,answer in zip(nonthermal_fluxden_idl,nonthermal_fluxden_answer):
         self.assertLess(np.abs(idl-answer)/answer,1.e-4)
     for idl,answer in zip(unatten_nonthermal_fluxden_idl,unatten_nonthermal_fluxden_answer):
         self.assertLess(np.abs(idl-answer)/answer,1.e-4)
Example #7
0
 def test_thermal_fluxden_2(self):
     contfreqs = np.array([10,40]) # GHz
     electron_temp = 5000. # K
     electron_dens = 1.e4 # cm-3
     HII_region_size = 10. # pc
     region_size = 1000. # pc
     distance = 3. # Mpc
     omega_HII_region = np.pi * (0.5*HII_region_size/(distance*1.e6))**2.
     omega_region = np.pi * (0.5*region_size/(distance*1.e6))**2.
     heII_abundance = 0.
     heIII_abundance = 0.
     tau_c_cont = utils.tau_c(electron_temp,electron_dens,HII_region_size,contfreqs,
                                    heII_abundance=heII_abundance,heIII_abundance=heIII_abundance)
     num_HII_regions = 1000.
     num_HII_regions_los = utils.num_HII_regions_los(num_HII_regions,HII_region_size,region_size)
     thermal_fluxden_answer = np.array([6.31444022e-24,5.9380819514121456e-24]) # W/m2/Hz
     thermal_fluxden_idl = np.array([6.3144821638610799e-21,5.9381215189383294e-21])*1.e-3 # W/m2/Hz
     thermal_fluxden_check = utils.thermal_fluxden(contfreqs,electron_temp,
                                                        omega_HII_region,omega_region,
                                                        tau_c_cont,num_HII_regions,num_HII_regions_los)
     for answer,check in zip(thermal_fluxden_answer,thermal_fluxden_check):
         self.assertLess(np.abs(check-answer)/answer,1.e-4)
     for idl,answer in zip(thermal_fluxden_idl,thermal_fluxden_answer):
         self.assertLess(np.abs(idl-answer)/answer,1.e-4)
Example #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