def params2spec(self,d,params,components=False): # start with the powerlaw spectrum: norm = params[0] # powerlaw norm (photons/s/keV/cm^2 at 1 keV) alpha = params[1] # photon index of powerlaw (dimensionless) nH = params[2] # in units of 10^22 atoms/cm^2 Espec = zeros(len(d.energies)) # powerlaw spectrum (ph/s/cm^2/keV) c1 = norm*d.energies**(-alpha) Espec += c1 # Sc line (adjust flux only): #Espec += lines.shell(d.energies, 4000, params[3].getValue()) c2 = lines.delta(d.energies, params[3]) #Espec += lines.spitzer(d.energies, params[3].getValue()) Espec += c2 comps = [c1,c2] # add the nuisance gaussian lines: npar = len(params) for i in [npar-6, npar-3]: # hard coded! 2 nuisance lines! area = params[i] # photons/s/cm^2 center = params[i+1] # keV sigma = params[i+2] # keV # ph/s/cm^2/keV : #Espec += area/sigma/sqrt(2*pi)*exp( -(self.energies-center)**2/2/sigma**2 ) cn = lines.gaussian(d.energies, area, center, sigma) Espec += cn comps.append(cn) # account for binning, which is \int_{E_l}^{E_h} dE S(E) dE = roll(d.energies,-1) - d.energies dE[-1] = dE[-2] # trapezoidal integration: dSpec = roll(Espec,-1) - Espec dSpec[-1] = dSpec[-2] Espec = dE*Espec - dE*dSpec/2 # ph/s/cm^2 Espec *= d.exposure # photons/cm^2 Espec *= self.transmission**nH # dimmer photons/cm^2 # for plotting purposes: if components: compsOut = [] for c in comps: dSpec = roll(c,-1) - c dSpec[-1] = dSpec[-2] c = dE*c - dE*dSpec/2 # ph/s/cm^2 c *= d.exposure c *= self.transmission**nH compsOut.append(c) return Espec, compsOut else: return Espec
def params2spec(self,params): # start with the powerlaw spectrum: norm = params[0].getValue() # powerlaw norm (photons/s/keV/cm^2 at 1 keV) alpha = params[1].getValue() # photon index of powerlaw (dimensionless) nH = params[2].getValue() # in units of 10^22 atoms/cm^2 # powerlaw spectrum (ph/s/cm^2/keV) Espec = norm*self.energies**(-alpha) # Sc line (adjust flux only): #Espec += lines.shell(self.energies, 4000, params[3].getValue()) Espec += lines.delta(self.energies, params[3].getValue()) #Espec += lines.spitzer(self.energies, params[3].getValue()) # add the nuisance gaussian lines: npar = len(params) for i in [npar-6, npar-3]: # hard coded! 2 nuisance lines! area = params[i].getValue() # photons/s/cm^2 center = params[i+1].getValue() # keV sigma = params[i+2].getValue() # keV # ph/s/cm^2/keV : #Espec += area/sigma/sqrt(2*pi)*exp( -(self.energies-center)**2/2/sigma**2 ) Espec += lines.gaussian(self.energies, area, center, sigma) # account for binning, which is \int_{E_l}^{E_h} dE S(E) dE = np.roll(self.energies,-1) - self.energies dE[-1] = dE[-2] # trapezoidal integration: dSpec = np.roll(Espec,-1) - Espec dSpec[-1] = dSpec[-2] Espec = dE*Espec - dE*dSpec/2 # ph/s/cm^2 Espec *= self.exposure # photons/cm^2 Espec *= self.transmission**nH # dimmer photons/cm^2 return Espec
def sourceSpectrum(E, linemode = 2, confused = True): ''' produce a true spectrum (pre-instrument) from parameters: params = [norm, alpha, Sc area, line 1 area, line 2 area] assuming 25 eV natural sigma for all lines; fix them at known energies modes: 0: delta 1: shell 2: broadened 3: spitzer ''' sourceComponents = [] # start with the powerlaw spectrum: norm = params[0] # powerlaw norm (photons/s/keV/cm^2 at 1 keV) alpha = params[1] # photon index of powerlaw (dimensionless) nH = params[2] # in units of 10^22 atoms/cm^2 # powerlaw spectrum (ph/s/cm^2/keV) c1 = norm*E**(-alpha) sourceComponents.append(c1) # Sc line (adjust flux only): if linemode == 0: c2 = lines.delta(E, params[3]) print 'delta function Sc line' elif linemode == 1: c2 = lines.shell(E, 2000, params[3]) print 'thin shell Sc line' elif linemode == 2: c2 = lines.gaussian(E, params[3], 4.09, 0.010) print 'broadened (10 eV sigma) Sc line' elif linemode == 3: c2 = lines.spitzer(E, params[3]) print 'spitzer Sc line' #print 'sc flux: %.2f' % (params[3]*1.7e5*388) sourceComponents.append(c2) # add the nuisance gaussian lines: for i in [4, 7]: # hard coded! 2 nuisance lines! area = params[i] # photons/s/cm^2 center = params[i+1] # keV s = params[i+2] # keV # ph/s/cm^2/keV : #Espec += area/sigma/sqrt(2*pi)*exp( -(self.energies-center)**2/2/sigma**2 ) ci = lines.gaussian(E, area, center, s) sourceComponents.append(ci) # confusing nearby lines: if confused: print 'confused spectrum' sourceComponents.append(lines.gaussian(E, params[3]*1.05, 4.22, 0.010)) sourceComponents.append(lines.gaussian(E, params[3]*0.85, 4.04, 0.012)) sourceComponents.append(lines.gaussian(E, params[3]*0.85, 4.22, 0.008)) sourceComponents.append(lines.gaussian(E, params[3]*1.45, 4.13, 0.015)) sourceComponents.append(lines.gaussian(E, params[3]*0.75, 3.98, 0.010)) for c in sourceComponents: c *= phabs**nH # absorption: dimmer ph/s/cm^2/kev return sourceComponents