def test_getTemDen(max_error=5e-3): pn.atomicData.setDataFile('o_iii_atom_SZ00-WFD96.dat') pn.atomicData.setDataFile('o_iii_coll_AK99.dat') atom = pn.Atom('O', 3) assert (rel_error(atom.getTemDen(100., den=10000., wave1=5007, wave2=4363), 11308.) < max_error) assert (rel_error(atom.getTemDen(1., tem=10000., wave1=88e4, wave2=52e4), 183) < max_error) pn.atomicData.setDataFile('o_ii_atom_Z82-WFD96.dat') pn.atomicData.setDataFile('o_ii_coll_P06-T07.dat') atom = pn.Atom('O', 2) assert (rel_error(atom.getTemDen(1.5, tem=10000., wave1=3726, wave2=3729), 1496) < max_error)
def _check_line_label_list(maxErrorA = 5.e-3, maxErrorm = 5.e-2): for ion in LINE_LABEL_LIST: if ion not in ('H1', 'He1', 'He2'): atom = pn.Atom(atom=ion) for line in LINE_LABEL_LIST[ion]: #print ion, line res = atom.getTransition(line, maxErrorA = maxErrorA, maxErrorm = maxErrorm)
def p1(): O3 = pn.Atom('O',3) # define the Atom object for O++ and fills it with data O3.printIonic() # print for each level the possible transitions and their wavelengths O3.printIonic(printA=True) # print, in addition the transition probabilities
def genEmisGrid(self, linesList, teRange, neRange): # Hbeta data H1 = pn.RecAtom('H', 1) HBeta = H1.getEmissivity(teRange, neRange, wave=4861, product=False) # Generate the emissivity grids for all the ions emis_dict = {'HBeta': HBeta} # Loop through the lines list: for i in range(len(linesList)): element, ionization, wave = linesList[i][0][:-1], linesList[i][0][ -1], linesList[i][1] line_label = '{}{}_{}A'.format(element, ionization, wave) if element in ['H', 'He']: ion = pn.RecAtom(element, ionization) if element == 'H': emis_dict[line_label] = ion.getEmissivity( teRange, neRange, wave=wave, product=False) / HBeta if element == 'He': emis_dict[line_label] = ion.getEmissivity( teRange, neRange, wave=wave, product=False) / HBeta else: ion = pn.Atom(element, ionization) emis_dict[line_label] = np.log10( ion.getEmissivity( teRange, neRange, wave=wave, product=False) / HBeta) return emis_dict
def test_line_labels(): """ This tool scans all the lines from pn.LINE_LABEL_LIST, extract the wavelength and compare with the wavelength given by the corresponding atom for the corresponding transition. Is the difference is greater than 1AA for optical or 0.1mu for IR, it prints the information """ for atom_str in pn.LINE_LABEL_LIST: try: if atom_str[0] == '3': atom = None elif atom_str[-1] == 'r': atom = pn.RecAtom(atom=atom_str) else: atom = pn.Atom(atom=atom_str) except: atom = None if atom is not None: if atom.NLevels != 0: for line in pn.LINE_LABEL_LIST[atom_str]: if line[-1] == 'm': wavelength = float(line[:-1]) * 1e4 else: wavelength = float(line[:-1]) i, j = atom.getTransition(wavelength) wave = atom.wave_Ang[i - 1, j - 1] if wave < 1e4: dif = np.abs(wavelength - wave) else: dif = np.abs(wavelength - wave) / 1e3 if dif > 1.0: print(atom, line) assert dif < 1.0
def test_atom_emissivity_shape(): pn.atomicData.setDataFile('o_iii_atom_SZ00-WFD96.dat') pn.atomicData.setDataFile('o_iii_coll_AK99.dat') atom = pn.Atom("O", 3) result = atom.getEmissivity(20000, 1e2) assert (result.shape == (6, 6)) result = atom.getEmissivity(20000, [1e2, 1e3]) assert (result.shape == (6, 6, 2)) result = atom.getEmissivity([20000, 10000], 1e2) assert (result.shape == (6, 6, 2)) result = atom.getEmissivity([20000, 10000], [1e2, 1e3]) assert (result.shape == (6, 6, 2, 2)) result = atom.getEmissivity([20000, 10000], [1e2, 1e3], product=True) assert (result.shape == (6, 6, 2, 2)) result = atom.getEmissivity([20000, 10000], [1e2, 1e3], product=False) assert (result is None) result = atom.getEmissivity(20000, 1e2, wave=5007) assert (result.shape == ()) result = atom.getEmissivity(20000, [1e2, 1e3], wave=5007) assert (result.shape == (2, )) result = atom.getEmissivity([20000, 10000], 1e2, wave=5007) assert (result.shape == (2, )) # the bug I'm looking for result = atom.getEmissivity([20000, 10000], [1e2, 1e3], wave=5007) assert (result.shape == (2, 2)) result = atom.getEmissivity([20000, 10000], [1e2, 1e3], product=True, wave=5007) assert (result.shape == (2, 2))
def p5(): # this will plot all the available data in pyneb for the omegas ions = [ 'C2', 'C3', 'N2', 'N3', 'O2', 'O3', 'O4', 'Ne2', 'Ne3', 'Ne5', 'S2', 'S3', 'S4', 'Cl3', 'Ar2', 'Ar3', 'Ar4', 'Ar5', ] for ion in ions: # split ion into elem and spec, e.g 'O3' into 'O' and 3 elem, spec = parseAtom(ion) # instanciate the corresponding Atom object atom = pn.Atom(elem, spec) # print information including transition probabilities #atom.printIonic(printA = True) dp = pn.DataPlot(elem, spec) dp.plotOmega(save=True)
def p5(den=1e2, style='-', legend=True, coeff=1.): # in parenthesis are the default options O3 = pn.Atom('O',3) if coeff != 1.: O3._A *= coeff # multiplies all the A values by coeff O3.plotEmiss(den=den, style=style, legend=legend) # defines a plot of line emissivities with updated A plt.ylim((-29, -19))
def p23(den=1e2, style='-', legend=True, ): # den=1e2, style='-', legend=True are the default options # other possible line styles for calling the function are '--','-.',':', and '.' O3 = pn.Atom('O',3) # define the Atom object for O++ and fills it with data # O3.plotEmiss? shows all the default parameters O3.plotEmiss(den=den, style=style, legend=legend) # function to plot the emissivities # O3.plotEmiss? shows all the default parameters plt.ylim((-29, -19)) # change the y limits on the current plot
def make_conf_plots(): at_list = [pn.Atom(atom=at) for at in ('C4', 'C3', 'C2', 'O3', 'O2', 'Ne3', 'Ne2')] f, axes = plt.subplots(4,2, figsize=(15, 30)) for at, ax in zip(at_list, axes.ravel()): at.plotGrotrian(ax=ax) f.savefig('conf_all.pdf')
def printAllSources(self, at_set=None, predef=None): """ Print bibliographic sources of the adopted data sets of a list of atoms. Usage: pn.atomicData.printAllSources(['O3', 'Ar4', 'S2']) pn.atomicData.printAllSources([O, S]) pn.atomicData.printAllSources() Parameters: - at_set a list or tuple containing the atoms. If not set, print bibliographic sources for all the atoms in PyNeb's default dictionary """ self.calling = 'printAllSources' if (type(at_set) == list) or (type(at_set) == tuple) or at_set == '': at_dict = {} for item in at_set: atom = parseAtom(item)[0] spec = parseAtom(item)[1] if spec is '': for ispec in SPEC_LIST: try: at_dict[atom + ispec] = pn.Atom(atom, ispec) except: pass else: at_dict[item] = pn.Atom(atom, spec) elif at_set is not None: pn.log_.error('The argument at_set must be a list or a tuple', calling=self.calling) return None elif (at_set is None) and (predef is None): at_dict = pn.getAtomDict() elif predef in pn.atomicData.getAllPredefinedDict(): current = pn.atomicData.predefined pn.atomicData.setDataFileDict(predef) at_dict = pn.getAtomDict() pn.atomicData.setDataFileDict(current) else: pn.log_.error( 'The argument predef must be the label of a predefined dictionary', calling=self.calling) for item in sorted(at_dict): at_dict[item].printSources()
def test_atom_props(): O3 = pn.Atom("O", 3) assert O3.elem == "O" assert O3.spec == 3 assert O3.atom == "O3" assert O3.getTransition(5007) == (4, 3)
def p7a(den=1e2, style='-', legend=True): atom = pn.Atom('O',3) tem_min = 1e2 tem_max = 1.e7 ionic_abund=1. atom.plotEmiss(tem_min=tem_min, tem_max=tem_max, den=den, ionic_abund=ionic_abund, style=style, legend=legend) plt.ylim((-25, -19))
def p4(): O3 = pn.Atom('O',3) print(O3) # Print the element and ionisation, with the names of the atomic data files print(O3.atomFile) # print the name of the atomic data file "atom" (containing Energies and transitions proba) print(O3.collFile) # print the name of the atomic data file "coll" (containg the Omegas) print(O3.atomPath) # print the directory where the atomFitsFile is read from print(O3.collPath) # print the directory where the collFitsFile is rwad from O3.printSources() # print the bibliographical sources from the atom and coll fits files.
def __init__(self, atom, ion, wave): if not isinstance(wave, tuple): if isinstance(wave, list): wave = tuple(wave) else: wave = tuple([wave]) self.wave = wave self.atom = pn.Atom(atom, ion)
def _coll_fits2ascii(filename, overwrite=None): """ Transform a *coll*.fits file into an *coll*.dat file. """ strs = filename.split('/')[-1].split('_') elem = strs[0].capitalize() spec = roman_to_int(strs[1]) pn.atomicData.setDataFile(filename.split('/')[-1]) atom = pn.Atom(elem, spec) #atom.printSources() fileout = '{}.dat'.format(filename.split('.')[0]) if overwrite is not True: if os.path.exists(fileout): erase = raw_input('{} exists, overwrite?'.format(fileout)) if erase != 'y': return fout = open(fileout, 'w') fout.write('*** {0}{1} collision strengths data\n'.format( elem, strs[1].upper())) str_ = '0 0' for t in atom.getTemArray(): str_ += ' {0:9.3e}'.format(t) str_ += '\n' fout.write(str_) for omega in atom.getOmegaArray(): j = strExtract(omega, 'Omega(', '->') i = strExtract(omega, '->', ')') omegs = strExtract(omega, '[', ']') str_ = '{0} {1}'.format(i, j) for omeg in omegs.split(): str_ += ' {0:9.3e}'.format(float(omeg)) str_ += '\n' fout.write(str_) for item in atom.CollData.CollHeader.iteritems(): if 'SPECTRUM' in item[0] or 'ATOM' in item[0] or 'GSCONFIG' in item[0]: fout.write('*** ' + item[0] + ' ' + str(item[1]) + '\n') if 'TUNIT1' == item[0]: fout.write('*** T_UNIT ' + str(item[1]) + '\n') if 'SOURCE' in item[0]: N_Source = item[0].split('SOURCE')[1] str_N_Source = str(N_Source.split('_')[0]) fout.write('*** ' + item[0] + ' ' + str(item[1]) + '\n') try: fout.write('*** NOTE' + str_N_Source + ' ' + atom.CollData.CollHeader.get('NOTE' + str_N_Source) + '\n') except: fout.write('*** NOTE' + str_N_Source + ' collision strengths \n') print('{} done'.format(fileout)) fout.close()
def electron_density(ratio_core, ratio_wing): S2 = pn.Atom('S', 2) Ne_core = S2.getTemDen(int_ratio=ratio_core, tem=1e4, wave1=6717, wave2=6731) Ne_wing = S2.getTemDen(int_ratio=ratio_wing, tem=1e4, wave1=6717, wave2=6731) return Ne_core, Ne_wing
def p1(ion): # split ion into elem and spec, e.g 'O3' into 'O' and 3 elem, spec = parseAtom(ion) # instanciate the corresponding Atom object atom = pn.Atom(elem, spec) # print information including transition probabilities #atom.printIonic(printA = True) # prepare a new figure plt.figure() # plot energy levels atom.plotGrotrian()
def p7c(den=1e2, style='-', legend=True, OmegaInterp='Cheb'): # OmegaInterp is the method for interpolation and extrapolation of omegas. # it can take the values 'Cheb' (default) or 'Linear' atom = pn.Atom('O',3, OmegaInterp=OmegaInterp) tem_min = 1e2 tem_max = 1.e7 ionic_abund=1. atom.plotEmiss(tem_min=tem_min, tem_max=tem_max, den=den, ionic_abund=ionic_abund, style=style, legend=legend, temLog=True) plt.ylim((-25, -19))
def test_getA(max_error=5e-3): pn.atomicData.setDataFile('o_iii_atom_SZ00-WFD96.dat') pn.atomicData.setDataFile('o_iii_coll_AK99.dat') atom = pn.Atom("O", 3) assert (rel_error(atom.getA(1, 1) + 1, 1.0) < max_error) assert (rel_error(atom.getA(2, 1), 2.62e-05) < max_error) assert (rel_error(atom.getA(3, 1), 3.17e-11) < max_error) assert (rel_error(atom.getA(4, 1), 2.41e-06) < max_error) assert (rel_error(atom.getA(3, 2), 9.76e-05) < max_error) assert (rel_error(atom.getA(4, 2), 0.0068) < max_error) assert (rel_error(atom.getA(5, 2), 0.215) < max_error)
def test_getOmega(max_error=5e-3): pn.atomicData.setDataFile('o_iii_atom_SZ00-WFD96.dat') pn.atomicData.setDataFile('o_iii_coll_AK99.dat') atom = pn.Atom("O", 3) assert (rel_error(atom.getOmega(10000, 2, 1), 0.522) < max_error) assert (rel_error(atom.getOmega(10000, 3, 1), 0.2573) < max_error) assert (rel_error(atom.getOmega(10000, 4, 1), 0.2434) < max_error) assert (rel_error(atom.getOmega(10000, 5, 1), 0.0321) < max_error) assert (rel_error(atom.getOmega(10000, 3, 2), 1.232) < max_error) assert (rel_error(atom.getOmega(10000, 4, 2), 0.73) < max_error) assert (rel_error(atom.getOmega(10000, 5, 2), 0.0962) < max_error) assert (rel_error(atom.getOmega(10000, wave=5007), 1.217) < max_error)
def p6(den=1e2, style='-', legend=True, coeff=1.): O3 = pn.Atom('O',3) if coeff != 1.: Ntrans = O3.collNLevels * (O3.collNLevels - 1) / 2 for i, rec in enumerate(O3._CollData): for j in np.arange(Ntrans-1)+1: rec[j] = rec[j] * coeff # multiplies all the omega values by coeff O3._CollData[i] = rec O3.initOmegas() # update some values depending on Omegas O3.plotEmiss(den=den, style=style, legend=legend) # defines a plot of line emissivities with updated omegas plt.ylim((-29, -19))
def addDiagsFromObs(self, obs): """ Add all the possible diagnostics that can be computed from an Observation object Usage: diags.addDiagsFromObs(obs) Parameter: obs an Observation object """ if not isinstance(obs, pn.Observation): pn.log_.error('The argument must be an Observation object', calling=self.calling + 'addDiagsFromObs') old_level = pn.log_.level def I(i, j): wave = atom.wave_Ang[i - 1, j - 1] corrIntens = obs.getLine(sym, spec, wave).corrIntens return corrIntens def L(wave): corrIntens = obs.getLine(sym, spec, wave).corrIntens return corrIntens def B(label): full_label = atom + '_' + label corrIntens = obs.getLine(label=full_label).corrIntens return corrIntens def S(label): full_label = atom + '_' + label + 'A' corrIntens = obs.getLine(label=full_label).corrIntens return corrIntens for label in diags_dict: atom, diag_expression, error = diags_dict[label] sym, spec, rec = parseAtom2(atom) if label == '[OII] 3727+/7325+c': try: diag_value = eval(diag_expression) except Exception as ex: pn.log_.level = old_level pn.log_.debug('Diag not valid {} {}'.format(label, diag_expression)) try: pn.log_.level = 1 diag_value = eval(diag_expression) pn.log_.level = old_level if atom not in self.atomDict: if rec == 'r': self.atomDict[atom] = pn.RecAtom(atom=sym+spec) else: self.atomDict[atom] = pn.Atom(atom=atom, NLevels=self.NLevels) self.addDiag(label) except Exception as ex: pn.log_.level = old_level pn.log_.debug('Diag not valid {} {}'.format(label, diag_expression))
def test_ion_abundance(max_error=5e-3): pn.atomicData.setDataFile('o_iii_atom_SZ00-WFD96.dat') pn.atomicData.setDataFile('o_iii_coll_AK99.dat') atom = pn.Atom("O", 3) assert (rel_error(atom.getIonAbundance(10000, 10000, 100, 4, 3), 3.62e-3) < max_error) assert (rel_error(atom.getIonAbundance(10000, 20000, 100, 4, 3), 5.662e-4) < max_error) assert (rel_error(atom.getIonAbundance(10000, 10000, 100, wave=5007), 3.62e-3) < max_error) assert (rel_error(atom.getIonAbundance(10000, 20000, 100, wave=5007), 5.662e-4) < max_error) pn.atomicData.setDataFile('s_ii_atom_PKW09.dat') pn.atomicData.setDataFile('s_ii_coll_TZ10.dat') atom = pn.Atom("S", 2) assert (rel_error(atom.getIonAbundance(200, 20000, 100, 3, 1), 2.295e-6) < max_error) pn.atomicData.setDataFile('o_ii_atom_Z82-WFD96.dat') pn.atomicData.setDataFile('o_ii_coll_P06-T07.dat') atom = pn.Atom("O", 2) assert (rel_error(atom.getIonAbundance(200, 20000, 1000, 3, 1), 1.548e-5) < max_error)
def test_atom_instanciation(): """ This tool try to instantiate all the atoms using all the atomic data. """ atoms = pn.atomicData.getAllAtoms() atoms.remove('3He2') for atom in atoms: for atom_file in pn.atomicData.getAllAvailableFiles(atom, 'atom'): for coll_file in pn.atomicData.getAllAvailableFiles(atom, 'coll'): #print atom, atom_file, coll_file try: pn.atomicData.setDataFile(atom_file) pn.atomicData.setDataFile(coll_file) atm = pn.Atom(atom=atom) assert atm.atom == atom except: assert None == atom for rec_file in pn.atomicData.getAllAvailableFiles(atom, 'rec'): try: pn.atomicData.setDataFile(rec_file) atm = pn.Atom(atom=atom) assert atm.atom == atom except: assert None == atom
def _atom_fits2ascii(filename): """ Transform a *atom*.fits file into an *atom*.dat file. """ strs = filename.split('/')[-1].split('_') elem = strs[0].capitalize() spec = roman_to_int(strs[1]) # type = strs[2] pn.atomicData.setDataFile(filename.split('/')[-1]) atom = pn.Atom(elem, spec) atom.printSources() print('') fileout = raw_input( 'Enter the name of the output file (between {0[0]}_{0[1]}_{0[2]}_ and .dat:' .format(strs)) fout = open('{0[0]}_{0[1]}_{0[2]}_{1}.dat'.format(strs, fileout), 'w') fout.write('Aij\n') # str_ = '' # for i in np.arange(atom.NLevels): # str_ += '1/s ' # str_ += '\n' str_ = '1/s ' * atom.NLevels + '\n' fout.write(str_) for a1 in atom.getA(): str_ = '' for a2 in a1: str_ += '{0:10.7e}'.format(a2) str_ += ' ' str_ += '\n' fout.write(str_) for item in atom.AtomData.AtomHeader.iteritems(): if 'SPECTRUM' in item[0] or 'ATOM' in item[0] or 'GSCONFIG' in item[0]: fout.write('*** ' + item[0] + ' ' + str(item[1]) + '\n') if 'NOTE' in item[0]: if 'Energy' not in item[1]: N_Note = item[0].split('NOTE')[1] str_N_Note = str(N_Note.split('_')[0]) fout.write('*** SOURCE' + str_N_Note + ' ' + atom.AtomData.AtomHeader.get('SOURCE' + str_N_Note) + '\n') fout.write('*** ' + item[0] + ' ' + str(item[1]) + '\n') fout.close()
def getTemDen_helper(inQ, outQ, atom, lev_i1, lev_j1, lev_i2, lev_j2, wave1, wave2, maxError, method, log, start_x, end_x, to_eval, nCut, maxIter, NLevels=None): ''' multiprocessing helper for getTemDen''' thisAtom = pn.Atom(atom=atom, NLevels=NLevels) for inputs in iter(inQ.get, 'STOP'): jobid = inputs[0] int_ratio = inputs[1] tem = inputs[2] den = inputs[3] res = thisAtom._getTemDen_1(int_ratio, tem=tem, den=den, lev_i1=lev_i1, lev_j1=lev_j1, lev_i2=lev_i2, lev_j2=lev_j2, wave1=wave1, wave2=wave2, maxError=maxError, method=method, log=log, start_x=start_x, end_x=end_x, to_eval=to_eval, nCut=nCut, maxIter=maxIter) outQ.put((jobid, res)) return
def get_OoH_2(error=None): obs = pn.Observation('NGC300.dat', corrected=True, errIsRelative=False) if error == '-': for i in np.arange(obs.n_lines): obs.lines[i].corrIntens *= 1. - obs.lines[i].corrError if error == '+': for i in np.arange(obs.n_lines): obs.lines[i].corrIntens *= 1. + obs.lines[i].corrError O3 = pn.Atom('O', 3) r_O3 = O3.getEmissivity(1e4, 1e3, wave=4959) / O3.getEmissivity( 1e4, 1e3, wave=5007) I = lambda label: obs.getLine(label=label).corrIntens R23 = (I('O2_3727A+') + I('O3_5007A') * (1 + r_O3)) / 100. x = np.log10(R23) OsH = 9.265 - 0.33 * x - 0.202 * x**2 - 0.207 * x**3 - 0.333 * x**4 return OsH
def test_atom_emissivity_values(error=5e-2): pn.atomicData.setDataFile('o_iii_atom_SZ00-WFD96.dat') pn.atomicData.setDataFile('o_iii_coll_SSB14.dat') atom = pn.Atom("O", 3) result = atom.getEmissivity(20000, 1e2) emi = [ 9.55e-22, 4.00e-28, 7.77e-22, 1.42e-24, 3.98e-21, 1.19e-20, 9.49e-23, 2.78e-25, 4.01e-22 ] a = [] for i in result: for j in i: if (j > 0): a.append(j) for aux in range(len(a) - 1): result = (a[aux] / emi[aux]) assert (rel_error(a[aux], emi[aux]) < error)
def get_OoH_4(Tlow, Thigh, Ne): obs = pn.Observation('NGC300.dat', corrected=True, errIsRelative=False) O3 = pn.Atom('O', 3) r_O3 = O3.getEmissivity(1e4, 1e3, wave=4959) / O3.getEmissivity( 1e4, 1e3, wave=5007) t2 = Tlow / 1e4 t3 = Thigh / 1e4 I = lambda label: obs.getLine(label=label).corrIntens R2 = I('O2_3727A+') / 100 R3 = I('O3_5007A') * (1 + r_O3) / 100. R = I('O3_4363A') / 100 R23 = R2 + R3 X23 = np.log10(R23) x2 = 1e-4 * Ne * t2**(-0.5) Opp = np.log10(R3) + 6.174 + 1.251 / t3 - 0.55 * np.log10(t3) Op = np.log10(R2) + 5.890 + 1.676 / t2 - 0.40 * np.log10(t2) + np.log10( 1 + 1.35 * x2) OsH = np.log10(10**Op + 10**Opp) return OsH