def add_lines(Z, abund, lldat, ebins, z1=False, z1_drv=False, \ broadening=False, broadenunits='A'): """ Add lines to spectrum, applying gaussian broadening. Add the lines in list lldat, with atomic number Z, to a spectrum delineated by ebins (these are the edges, in keV). Apply broadening to the spectrum if broadening != False, with units of broadenunits (so can do constant wavelength or energy broadening) Parameters ---------- Z : int Element of interest (e.g. 6 for carbon) abund : float Abundance of element, relative to AG89 data. lldat : dtype linelist The linelist to add. Usually the hdu from the apec_line.fits \ file, often with some filters pre-applied. ebins : array of floats Energy bins. Will return spectrum with nbins-1 data points. z1 : int Ion charge +1 of ion to return z1_drv : int Driving Ion charge +1 of ion to return broadening : float Apply spectral broadening if > 0. Units of A of keV broadenunits : {'A' , 'keV'} The units of broadening, Angstroms or keV Returns ------- array of float broadened emissivity spectrum, in photons cm^3 s^-1 bin^-1. Array has \ len(ebins)-1 values. """ # # History # ------- # Version 0.1 - initial release # Adam Foster July 17th 2015 # lammax = (const.HC_IN_KEV_A/ebins[0]) lammin = (const.HC_IN_KEV_A/ebins[-1]) if broadenunits.lower() in ['a','angstrom','angstroms']: bunits = 'a' elif broadenunits.lower() =='kev': bunits = 'kev' else: print "Error: unknown broadening unit %s, Must be keV or A. Exiting ***"%\ (broadenunits) return -1 if broadening: if bunits == 'a': lammax += broadening lammin -= broadening else: lammax += lammax**2 * broadening/const.HC_IN_KEV_A lammin -= lammin**2 * broadening/const.HC_IN_KEV_A l = lldat[(lldat['element']==Z) &\ (lldat['lambda'] <= lammax) &\ (lldat['lambda'] >= lammin)] if z1: l = l[l['ion'] ==z1] if z1_drv: l = l[l['ion_drv'] ==z1_drv] spectrum = numpy.zeros(len(ebins)-1, dtype=float) if broadening: if bunits == 'a': for ll in l: spectrum+=atomdb.addline2(ebins, const.HC_IN_KEV_A/ll['lambda'], \ ll['epsilon']* abund,\ broadening*const.HC_IN_KEV_A/(ll['lambda']**2)) else: for ll in l: spectrum+=atomdb.addline2(ebins, const.HC_IN_KEV_A/ll['lambda'], \ ll['epsilon']* abund,\ broadening) else: for ll in l: spectrum[numpy.argmax(\ numpy.where(ebins < const.HC_IN_KEV_A/ll['lambda'])[0])]+=\ ll['epsilon']* abund return spectrum
def broaden_continuum(bins, spectrum, binunits = 'keV', \ broadening=False,\ broadenunits='keV'): """ Apply a broadening to the continuum Parameters ---------- bins : array(float) The bin edges for the spectrum to be calculated on, in units of \ keV or Angstroms. Must be monotonically increasing. Spectrum \ will return len(bins)-1 values. spectrum : array(float) The emissivities in each bin in the unbroadened spectrum binunits : {'keV' , 'A'} The energy units for bins. "keV" or "A". Default keV. broadening : float Broaden the continuum by gaussians of this width (if False,\ no broadening is applied) broadenunits : {'keV' , 'A'} Units for broadening (kev or A) Returns ------- array(float) spectrum broadened by gaussians of width broadening """ # History # ------- # Version 0.1 - initial release # Adam Foster July 17th 2015 # convert to energy grid if binunits.lower() in ['kev']: angstrom = False elif binunits.lower() in ['a','angstrom','angstroms']: angstrom = True else: print "*** ERROR: unknown units %s for continuum spectrum. Exiting" %\ (binunits) if angstrom: bins = const.HC_IN_KEV_A/bins[::-1] # broadening if broadening: if broadenunits.lower() in ['a','angstrom','angstroms']: bunits = 'a' elif broadenunits.lower() in ['kev']: bunits = 'kev' else: print "*** ERROR: unknown units %s for continuum broadening. Exiting" %\ (broadenunits) return -1 # do the broadening spec = numpy.zeros(len(spectrum)) emid = (bins[1:]+bins[:-1])/2 if broadenunits == 'a': # convert to keV broadenvec = const.HC_IN_KEV_A/emid else: broadenvec = numpy.zeros(len(emid)) broadenvec[:] = emid for i in range(len(spec)): spec += atomdb.addline2(bins, emid[i], \ spectrum[i],\ broadenvec[i]) spectrum=spec if angstrom: spectrum=spectrum[::-1] return spectrum