Ejemplo n.º 1
0
def test_abundance():
    # Float value
    _tmp_ion = ion(test_ion,abundance=0.01,setup=False)
    assert _tmp_ion.Abundance==0.01
    # FIXME: if setting custom abundance, AbundanceName should not be set, but right
    # now it is by the proton/electron density ratio calculation.
    # Custom filename
    _tmp_ion = ion(test_ion,abundance='sun_coronal_2012_schmelz',setup=False)
    assert _tmp_ion.AbundanceName=='sun_coronal_2012_schmelz'
    abundance = ch_tools.io.abundanceRead(abundancename='sun_coronal_2012_schmelz')
    assert _tmp_ion.Abundance==abundance['abundance'][_tmp_ion.Z-1]
Ejemplo n.º 2
0
def test_abundance():
    # Float value
    _tmp_ion = ion(test_ion, temperature = temperature_1, eDensity = density_1, abundance=0.01, setup=False)
    assert _tmp_ion.Abundance == 0.01
    # FIXME: if setting custom abundance, AbundanceName should not be set, but right
    # now it is by the proton/electron density ratio calculation.
    # Custom filename
    _tmp_ion = ion(test_ion, temperature = temperature_1, eDensity = density_1, abundance='sun_coronal_2012_schmelz', setup=False)
    assert _tmp_ion.AbundanceName == 'sun_coronal_2012_schmelz'
    abundance = ch_tools.io.abundanceRead(abundancename='sun_coronal_2012_schmelz')
    assert _tmp_ion.Abundance == abundance['abundance'][_tmp_ion.Z-1]
Ejemplo n.º 3
0
def print_elvlc(ion="c_4"):
    """
    Print out values of information in the Elvlc file that might be used 
    """
    x = ch.ion(ion, temperature=1e5)
    imax = len(x.Elvlc["lvl"])
    print(imax)
    i = 0
    while i < imax:
        if x.Elvlc["l"][i] % 2 == 1:
            p = 1
        else:
            p = 0
        islp = x.Elvlc["spin"][i] * 100 + x.Elvlc["l"][i] * 10 + p
        e = x.Ip - x.Elvlc["erydth"][i] * 13.605693009
        pretty = x.Elvlc["pretty"][i]
        pretty = pretty.replace(" ", "_")
        print("%2d %10s %d %s %d %5.1f %5.1f %15s  %3d %10.5f" % (
            x.Elvlc["lvl"][i],
            x.Elvlc["term"][i],
            x.Elvlc["spin"][i],
            x.Elvlc["spd"][i],
            x.Elvlc["l"][i],
            x.Elvlc["j"][i],
            x.Elvlc["mult"][i],
            pretty,
            islp,
            e,
        ))
        i += 1
Ejemplo n.º 4
0
def doIonQ(inQueue, outQueue):
    """
    Multiprocessing helper for `ChiantiPy.core.ion` and `ChiantiPy.core.ion.twoPhoton`

    Parameters
    -----------
    inQueue : `~multiprocessing.Queue`
        Jobs queued up by multiprocessing module
    outQueue : `~multiprocessing.Queue`
        Finished jobs
    """
    for inpts in iter(inQueue.get, 'STOP'):
        ionS = inpts[0]
        temperature = inpts[1]
        density = inpts[2]
        wavelength = inpts[3]
        wvlRange = [wavelength.min(), wavelength.max()]
        filter = inpts[4]
        allLines = inpts[5]
        abund = inpts[6]
        em = inpts[7]
        doContinuum = inpts[8]
        thisIon = ch.ion(ionS, temperature, density, abundance=abund)
        thisIon.intensity(wvlRange = wvlRange, allLines = allLines, em=em)
        if 'errorMessage' not in sorted(thisIon.Intensity.keys()):
            thisIon.spectrum(wavelength,  filter=filter)
        outList = [ionS, thisIon]
        if not thisIon.Dielectronic and doContinuum:
            if (thisIon.Z - thisIon.Ion) in [0, 1]:
                thisIon.twoPhoton(wavelength)
                outList.append(thisIon.TwoPhoton)
        outQueue.put(outList)
    return
Ejemplo n.º 5
0
def get_phot(ion="c_4"):
    """
    Obtain the photoionization x-sectons from TopBase. This routine uses 
    normal astronomical terminology, that is CIV would be element 6 and 
    ion 4
    
    First check if we already have the data, and if not retrieve it
    
    Note that the TopBase file names are based on the element number and the 
    number of electrons that the ion of interest has, but we convert to
    astronomical notation in this routine
    """
    x = ch.ion(ion, temperature=1e5)
    nelec = x.Z - x.Ion + 1
    fileroot = "p%02d.%02d" % (x.Z, nelec)
    outroot = "p%02d.%02d" % (x.Z, x.Ion)
    print("Looking for ", fileroot)
    if os.path.isfile("%s.txt" % outroot):
        print("TopBase Phot file for element %d and ion %d exists" %
              (x.Z, x.Ion))
        return
    os.system("wget cdsweb.u-strasbg.fr/topbase/p/%s.gz" % (fileroot))
    os.system("gunzip %s.gz" % (fileroot))
    os.system("mv %s %s.txt" % (fileroot, outroot))
    print(
        "TopBase Phot file for element %s and ion %d has now been retrieved" %
        (x.Z, x.Ion))
    return
Ejemplo n.º 6
0
 def rec_rate(network):
     ion = ch.ion(ion_name, temperature=network.T)
     # for some reason, the latest chiantipy
     # failed to update the tempeature for fully ionized
     ion.Temperature = network.T
     ion.recombRate()
     vals = ion.RecombRate['rate']
     return vals
Ejemplo n.º 7
0
def test_temperature_density():
    # TODO: test case where neither are set/ one or the other is not set
    # Two single values
    _tmp_ion = ion(test_ion,
                   temperature=temperature_1,
                   eDensity=density_1,
                   setup=True)
    assert _tmp_ion.Temperature == np.array(temperature_1)
    assert _tmp_ion.EDensity == np.array(density_1)
    # Multiple temperatures, one density
    _tmp_ion = ion(test_ion,
                   temperature=temperature_2,
                   eDensity=density_1,
                   setup=True)
    assert np.all(_tmp_ion.Temperature == temperature_2)
    assert np.all(_tmp_ion.EDensity == np.array(temperature_2.size *
                                                [density_1]))
    # One temperature, multiple densities
    _tmp_ion = ion(test_ion,
                   temperature=temperature_1,
                   eDensity=density_2,
                   setup=True)
    assert np.all(_tmp_ion.Temperature == np.array(density_2.size *
                                                   [temperature_1]))
    assert np.all(_tmp_ion.EDensity == density_2)
    # Two equal-sized temperature and density arrays
    _tmp_ion = ion(test_ion,
                   temperature=temperature_2,
                   eDensity=density_2,
                   setup=True)
    assert np.all(_tmp_ion.Temperature == temperature_2)
    assert np.all(_tmp_ion.EDensity == density_2)
    # Two unequal sized temperature and density arrays
    with pytest.raises(
            ValueError,
            message=
            '''Expecting ValueError when temperature and density are not of
                                equal size.'''):
        _tmp_ion = ion(test_ion,
                       temperature=temperature_2,
                       eDensity=density_3,
                       setup=True)
Ejemplo n.º 8
0
 def ion_rate(network):
     ion = ch.ion(ion_name, temperature=network.T)
     try:
         ion.ionizRate()
     except AttributeError:
         print(f"{ion_name} is not defined in ChiantiPy master list")
         print(f"manually adding temperature to {ion_name}_ion")
         ion.Temperature = network.T
         ion.NTempDens = len(network.T)
         ion.ionizRate()
     vals = ion.IonizRate['rate']
     return vals
Ejemplo n.º 9
0
def test_temperature_density():
    # TODO: test case where neither are set/ one or the other is not set
    # Two single values
    _tmp_ion = ion(test_ion,temperature=temperature_1,eDensity=density_1,setup=False)
    assert _tmp_ion.Temperature==np.array(temperature_1)
    assert _tmp_ion.EDensity==np.array(density_1)
    # Multiple temperatures, one density
    _tmp_ion = ion(test_ion,temperature=temperature_2,eDensity=density_1,setup=False)
    assert np.all(_tmp_ion.Temperature==temperature_2)
    assert np.all(_tmp_ion.EDensity==np.array(temperature_2.size*[density_1]))
    # One temperature, multiple densities
    _tmp_ion = ion(test_ion,temperature=temperature_1,eDensity=density_2,setup=False)
    assert np.all(_tmp_ion.Temperature==np.array(density_2.size*[temperature_1]))
    assert np.all(_tmp_ion.EDensity==density_2)
    # Two equal-sized temperature and density arrays
    _tmp_ion = ion(test_ion,temperature=temperature_2,eDensity=density_2,setup=False)
    assert np.all(_tmp_ion.Temperature==temperature_2)
    assert np.all(_tmp_ion.EDensity==density_2)
    # Two unequal sized temperature and density arrays
    with pytest.raises(ValueError,
                        message='''Expecting ValueError when temperature and density are not of
                                equal size.'''):
        _tmp_ion = ion(test_ion,temperature=temperature_2,eDensity=density_3,setup=False)
Ejemplo n.º 10
0
def match_line(ion_name, wvls, s_flux, tmax, density):

    #	t = 10**((tmax - 0.3) + 0.001*np.arange(600))

    lowtemp = 4.0
    hightemp = 8.0
    npoints = 1000
    t = 10**(np.linspace(lowtemp, hightemp, npoints))

    print("HERE WE GO")

    ion_n = ch.ion(ion_name, temperature=t, eDensity=density)

    print("LET'S GO")

    ion_n.gofnt(wvlRange=[min(wvls) - 1, max(wvls) + 1])

    return ion_n.Gofnt
Ejemplo n.º 11
0
def old_e_measure(ion_name, wvls, s_flux, tmax, star_dist, star_radius, density):


	rs = 6.96e10
	pc = 3.08567758e18
	t = 10**((tmax - 0.3) + 0.001*np.arange(600))
	ion_n = ch.ion(ion_name, temperature=t, eDensity=density)

	ion_n.gofnt(wvlRange=[min(wvls)-1,max(wvls)+1])
	star_dist = star_dist*pc
	star_radius = star_radius*rs

	flux = s_flux*(star_dist/star_radius)**2.0

	print('ANYONE THERE?!')
	quit()

	ion_n.Gofnt['emeasure'] = (flux/density) / (2*np.pi*ion_n.Gofnt['gofnt'])
	return ion_n.Gofnt
Ejemplo n.º 12
0
def old_find_tm(ion_name):

    h = 6.626068e-34
    c = 299792458
    k = 1.3806503e-23

    ion_state = int(ion_name.rsplit('_')[1])

    t = 10**(3.8+ 0.01*np.arange(400))

    ion = ch.ion(ion_name, temperature=t)

    ioneq = ion.IoneqOne
    W =  h*c*ion.Elvlc['ecm'][ion_state - 1]*100
    gt = ioneq*(t**-0.5)*np.exp(-W/(k*t))

    tm = t[np.argmax(gt)]

    return np.log10(tm)
Ejemplo n.º 13
0
def sum_match_lines(ion_name, wvls, t, density, search_width=1.0):

    ion_n = ch.ion(ion_name, temperature=t, eDensity=density)

    intensity = t.copy() * 0.0
    print(wvls)
    for wvl in wvls:
        #    ion_n.intensity(wvlRange=[min(wvls)-search_width,max(wvls)+search_width])
        ion_n.intensity()

        if wvl in (ion_n.Intensity['wvl']):
            intensity_s = ion_n.Intensity['intensity'][:, (
                ion_n.Intensity['wvl'] == wvl)]
            intensity += np.array(intensity_s.T[0])
            print('match')
        else:
            print('Something is wrong - cannot find matching line! for {} {}'.
                  format(ion_name, wvl))
            intensity += 0
    return intensity
Ejemplo n.º 14
0
from ChiantiPy.core import ion,ioneq
import ChiantiPy.tools as ch_tools

# use an ion with relatively small chianti files
test_ion = 'fe_15'
# TODO: probably should check a few different ions, i.e. dielectronic, some without certain kinds
# files, etc.
# set a few temperature and density arrays
temperature_1 = 1e+6
temperature_2 = np.logspace(5,8,20)
density_1 = 1e+9
density_2 = np.logspace(5,8,20)
density_3 = np.logspace(5,8,21)
# setup an ion object to reuse in several tests
tmp_ion = ion(test_ion,temperature=temperature_2,eDensity=density_2)


#Check various ways to specify the temperature and density
def test_temperature_density():
    # TODO: test case where neither are set/ one or the other is not set
    # Two single values
    _tmp_ion = ion(test_ion,temperature=temperature_1,eDensity=density_1,setup=False)
    assert _tmp_ion.Temperature==np.array(temperature_1)
    assert _tmp_ion.EDensity==np.array(density_1)
    # Multiple temperatures, one density
    _tmp_ion = ion(test_ion,temperature=temperature_2,eDensity=density_1,setup=False)
    assert np.all(_tmp_ion.Temperature==temperature_2)
    assert np.all(_tmp_ion.EDensity==np.array(temperature_2.size*[density_1]))
    # One temperature, multiple densities
    _tmp_ion = ion(test_ion,temperature=temperature_1,eDensity=density_2,setup=False)
Ejemplo n.º 15
0
def chianti_excitation_rates_fn(chianti_string, temps, eDens, no_levels):
    """ now we need to load in the Chianti data for CaII """
    chianti_ion = ch.ion(chianti_string, temperature=temps, eDensity=eDens)
    chianti_ion.upsilonDescale()
    lower_lvl_index = chianti_ion.Scups["lvl1"]
    upper_lvl_index = chianti_ion.Scups["lvl2"]
    exRates = chianti_ion.Upsilon["exRate"]
    dexRates = chianti_ion.Upsilon["dexRate"]

    # squeeze the ex and dex lists as they are multi-D but really are 1D
    exRates = np.squeeze(exRates)
    dexRates = np.squeeze(dexRates)

    chianti_ion_collision_df = pd.DataFrame(
        {
            "lower_lvl": lower_lvl_index,
            "upper_lvl": upper_lvl_index,
            "Chianti_exRate": exRates,
            "Chianti_dexRate": dexRates,
        }
    )
    # print(chianti_ion_collision_df)
    indexes = chianti_ion_collision_df[
        chianti_ion_collision_df["upper_lvl"] > no_levels
    ].index
    # print(indexes)
    chianti_ion_collision_df = chianti_ion_collision_df.drop(indexes.values)
    # print(chianti_ion_collision_df)

    # building df from Chianti for the wavelength, gf, A-values for transitions
    wgfa_lower_lvl = chianti_ion.Wgfa["lvl1"]
    wgfa_upper_lvl = chianti_ion.Wgfa["lvl2"]
    wgfa_lambda = chianti_ion.Wgfa["wvl"]
    wgfa_A = chianti_ion.Wgfa["avalue"]
    chianti_ion_transition_df = pd.DataFrame(
        {
            "lower_lvl": wgfa_lower_lvl,
            "upper_lvl": wgfa_upper_lvl,
            "Chianti_lambda(AA)": wgfa_lambda,
            "Chianti_A-value(s-1)": wgfa_A,
        }
    )
    # print(chianti_ion_transition_df)
    indexes = chianti_ion_transition_df[
        chianti_ion_transition_df["upper_lvl"] > no_levels
    ].index
    # print(indexes)
    chianti_ion_transition_df = chianti_ion_transition_df.drop(indexes.values)
    # print(chianti_ion_transition_df)

    chianti_ion_df = pd.merge(
        chianti_ion_collision_df,
        chianti_ion_transition_df,
        on=["lower_lvl", "upper_lvl"],
        how="left",
    )
    # print(chianti_ion_df)

    # later on, our code will crash if we don't have an entry in chianti_ion_df
    # for every downward transition, so here we append any missing ones to the
    # end of the df, and fill with zeros
    for ii in range(no_levels):  # column no./initial level
        for jj in range(no_levels):  # row no./final level
            # the indices will be 1 less than Chianti level indices
            if ii < jj:
                # checking whether the downward transition exists in
                # chianti_ion_df
                if (
                    any(
                        (chianti_ion_df.lower_lvl == ii + 1)
                        & (chianti_ion_df.upper_lvl == jj + 1)
                    )
                    is False
                ):
                    # print("we don't have a line for this transition:",
                    #       ii + 1, jj + 1)
                    chianti_ion_df.loc[len(chianti_ion_df)] = 0
                    chianti_ion_df.lower_lvl.loc[len(chianti_ion_df) - 1] = (
                        ii + 1
                    )
                    chianti_ion_df.upper_lvl.loc[len(chianti_ion_df) - 1] = (
                        jj + 1
                    )
    # print(chianti_ion_df)

    return (chianti_ion, chianti_ion_df)
Ejemplo n.º 16
0
def doit(atom="h_1", nlev=10):
    """
    Do something magnificent

    Description:

    Notes:

    History:


    """
    nlev = int(nlev)

    xion = ch.ion(atom, temperature=1e5)
    xlevels = get_levels(atom, nlev)

    # If we could not find the number of levels
    # requested, reduce the number so that the
    # rest of the routines will not generate more comments on this
    if len(xlevels) < nlev:
        nlev = len(xlevels)

    # Find the ionization potential of lower ionization
    # states as well

    ex_offset = 0
    i = 1
    while i < xion.Ion:
        words = atom.split("_")
        element_string = "%s_%d" % (words[0], i)
        xx = ch.ion(element_string, 1e5)
        ex_offset += xx.Ip
        i += 1

    xlevels.add_row([
        "LevMacro",
        xion.Z,
        xion.Ion + 1,
        1,
        0.00000,
        xion.Ip + ex_offset,
        1,
        1.00e21,
        "Next",
        0,
        0,
    ])
    xlevels.write(atom + "_levels.dat",
                  format="ascii.fixed_width_two_line",
                  overwrite=True)
    xlines = get_lines(atom, nlev)
    xlines.write(atom + "_lines.dat",
                 format="ascii.fixed_width_two_line",
                 overwrite=True)

    get_phot(atom)
    make_phot(atom)
    write_phot(atom)

    xcol = get_collisions(atom, nlev)
    return
Ejemplo n.º 17
0
import ChiantiPy.core as ch
import numpy as np
import ChiantiPy.tools.filters as chfilters
import matplotlib.pyplot as plt

t = 10.**(3.84 + 0.05 * np.arange(8.))
H1 = ch.ion('h_1', temperature=t, eDensity=1.e+14, em=1.e+27)
H1.popPlot(top=10)
H1.intensityPlot(wvlRange=[6564, 6565], linLog='log', index=4, top=10)
H1.intensityList(wvlRange=[4000, 7000], index=4, top=10)
plt.show(H1)

H1a = ch.ioneq(1)
H1a.load()
H1a.plot()
#plt.xlim(0,3e4)
plt.tight_layout()
plt.show(H1a)
Ejemplo n.º 18
0
def get_levels(ion="h_1", nlevels=10):
    """
    Extract the information needed to write out the
    the levels file, and return it as an astropy Table.
    
    Note:  In Keara's notes, she derives the multiplicity
    from J, but the multiplicity can be accessed directly
    
    This returns the information needed to write out a level
    file.  Depending on whether one plans to include more
    ions, one needs to add a dummy line for the next ion up
    for the purposes of created a full data set.

    The excitation energy has to be conistent across ions
    
    Python can read the astropy table for levels directly,
    so normally one would write this to a file
    """
    x = ch.ion(ion, temperature=1e5)
    First_Ion_Pot = x.Ip

    # Find the ionization potential of lower ionization
    # states as well

    ex_offset = 0
    i = 1
    while i < x.Ion:
        words = ion.split("_")
        element_string = "%s_%d" % (words[0], i)
        xx = ch.ion(element_string, 1e5)
        ex_offset += xx.Ip
        i += 1

    n = 0
    lvl = []
    rad_rate = []
    ex_energy = []
    g = []
    ion_pot = []
    islp = []
    configuration = []
    if len(x.Elvlc["lvl"]) < nlevels:
        print("There are only %d levels, not %d as requested" %
              (len(x.Elvlc["lvl"]), nlevels))
        nlevels = len(x.Elvlc["lvl"])
    while n < nlevels:
        lv = x.Elvlc["lvl"][n]
        lvl.append(lv)
        if lv == 1:
            rad_rate.append(1e21)
        else:
            rad_rate.append(1e-9)

        #  Calculate the parity.  Note that one cannot calculate the parity from
        #  L in LS coupling.  It is calculated from the the indidual l's of the
        #  electrons in unfilled shells.  It is given by the number of electrons
        #  in the p, f, or h orbitals, so for a term of 2s2p3, which means you 1
        #  electorn in the 2s state and 3 in the 2p state, you count to 3, and
        #  this has odd parity, which is 1 in our notation.  This information is
        #  contained in the term

        term = x.Elvlc["term"][n]
        xterm = list(term)

        j = 0
        num = 0
        while j < len(xterm):
            if xterm[j] == "p" or xterm[j] == "f" or xterm[j] == "h":
                try:
                    delta = int(xterm[j + 1])
                except:
                    delta = 1
                num += delta
            j += 1

        # print('%14s %2d' % (term,num))

        parity = num % 2
        # if x.Elvlc["l"][n] % 2 == 1:
        #     p = 1
        # else:
        #     p = 0

        xislp = x.Elvlc["spin"][n] * 100 + x.Elvlc["l"][n] * 10 + parity
        islp.append(xislp)
        ex = x.Elvlc["ecm"][n] / 8065.5
        ex_energy.append(ex)
        # g.append(x.Elvlc['j'][n]*2+1)
        g.append(x.Elvlc["mult"][n])
        ion_pot.append(-(First_Ion_Pot - ex))
        pretty = x.Elvlc["pretty"][n]
        pretty = pretty.replace(" ", "_")
        configuration.append(pretty)
        n += 1

    # Before setting up the table add the offset to ex
    ex_energy = np.array(ex_energy) + ex_offset

    xtab = Table(
        [lvl, ion_pot, ex_energy, g, rad_rate, configuration, islp],
        names=["lvl", "ion_pot", "ex", "g", "rad_rate", "config", "islp"],
    )
    xtab["Element"] = x.Z
    xtab["Ion"] = x.Ion
    xtab["Dtype"] = "LevMacro"
    xxtab = xtab["Dtype", "Element", "Ion", "lvl", "ion_pot", "ex", "g",
                 "rad_rate", "config", "islp", ]
    xxtab["ion_pot"].format = ".6f"
    xxtab["ex"].format = ".6f"

    # Now try to set up the TopBass Ilv for this file
    # The approach here is to use the absolute value of the
    # difference in the energy, but this may not be ideal.

    qslp = np.unique(xxtab["islp"])

    xxtab["ilv"] = -99
    #    for q in qslp:
    #        i = 0
    #        n = 0
    #        e_old = 0
    #        while i < len(xxtab):
    #            if xxtab["islp"][i] == q:
    #                if n == 0:
    #                    e_old = xxtab["ex"][i]
    #                    n += 1
    #                elif abs(xxtab["ex"][i] - e_old) < 0.1:
    #                    pass
    #                else:
    #                    e_old = xxtab["ex"][i]
    #                    n += 1
    #                xxtab["ilv"][i] = n
    #            i += 1

    # This is an alternative, which simply assumes that
    # All of the sublevels are displayed at once

    #    xxtab["ilv"] = -99
    #    for q in qslp:
    #        i = 0
    #        n = 0
    #        while i < len(xxtab):
    #            if xxtab["islp"][i] == q:
    #                if n==0:
    #                    i_old=i
    #                    n+=1
    #                elif i_old+1==i:
    #                    i_old=i
    #                else:
    #                    i_old=i
    #                    n+=1
    #                xxtab["ilv"][i] = n
    #            i+=1

    # Use the term to idenfify all of the sublevels that are associated with
    # one topbase level. This approach assumes that all fo the sublevels assoicated
    # with a single level are contiguous in the Elvlc dictionary.
    for q in qslp:
        i = 0
        n = 0
        term_old = ""
        while i < len(xxtab):
            if xxtab["islp"][i] == q:
                if n == 0:
                    term_old = x.Elvlc["term"][i]
                    n += 1
                elif x.Elvlc["term"][i] == term_old:
                    pass
                else:
                    term_old = x.Elvlc["term"][i]
                    n += 1
                xxtab["ilv"][i] = n
            i += 1

    return xxtab
Ejemplo n.º 19
0
import ChiantiPy.core as ch

for s in (ion_by_ion.required_species):
    print(s, type(s))

if start_neutral:
    for s in ion_by_ion.required_species:
        if getattr(s, 'free_electrons', -1) == 0:
            init_values[s.name] = init_array.copy()
        else:
            init_values[s.name] = X * init_array
        # Scale to solar abundances
        if s.name not in ['de', 'ge']:
            ion_name = s.name.lower()
            ion = ch.ion(ion_name, temperature=init_values['T'])
            init_values[s.name] *= ion.Abundance

    init_values['de'][:] = 1e-30
    init_values = ion_by_ion.convert_to_mass_density(init_values)
else:
    # start CIE

    for s in sorted(ion_by_ion.required_species):
            if s.name != 'ge':
                if s.name == 'de':
                    continue
                else:
                    ion_name = s.name.lower()
                    ion = ch.ion(ion_name, temperature=init_values['T'])
                    print(ion_name)
Ejemplo n.º 20
0

__author__  = 'Wayne Green'
__version__ = '0.1'



##############################################################################
#                                    Main
#                               Regression Tests
##############################################################################
# HEREHEREHERE
if __name__ == "__main__":
   opts = optparse.OptionParser(usage="%prog "+__doc__)

   opts.add_option("-v", "--verbose", action="store_true", dest="verboseflag",
                   default=False,
                   help="<bool>     be verbose about work.")

   (options, args) = opts.parse_args()

   #if(len(args) == 0 ): args.append(None)

   t = 10.**(5.8 + 0.05*np.arange(21.))
   
   fe14 = ch.ion('fe_14', temperature=t, eDensity=1.e+9, em=1.e+27)
   
   fe14.popPlot()


Ejemplo n.º 21
0
import ChiantiPy.tools as ch_tools

# use an ion with relatively small chianti files
#test_ion = 'fe_15'
# want an ion with auto-ionization rates
test_ion = 'o_6'
# TODO: probably should check a few different ions, i.e. dielectronic, some without certain kinds
# files, etc.
# set a few temperature and density arrays
temperature_1 = 1e+6
temperature_2 = np.logspace(5, 8, 20)
density_1 = 1e+9
density_2 = np.logspace(5, 8, 20)
density_3 = np.logspace(5, 8, 21)
# setup an ion object to reuse in several tests
tmp_ion = ion(test_ion, temperature=temperature_2, eDensity=density_2)


# Check various ways to specify the temperature and density
def test_temperature_density():
    # TODO: test case where neither are set/ one or the other is not set
    # Two single values
    _tmp_ion = ion(test_ion,
                   temperature=temperature_1,
                   eDensity=density_1,
                   setup=True)
    assert _tmp_ion.Temperature == np.array(temperature_1)
    assert _tmp_ion.EDensity == np.array(density_1)
    # Multiple temperatures, one density
    _tmp_ion = ion(test_ion,
                   temperature=temperature_2,
Ejemplo n.º 22
0
def get_lines(ion="h_4", nlevels=10):
    """
    Given an astropy table that contains all of the levels, 
    get the associated line information.
    
    Notes:
    This routine calls get_lev to decide which lines to retrieve
    so that it only produces a table with lines for which levels
    are known

    There are some lines in the Chianti database that have 0 wavelength.
    These are all strictly forbidden lines, but Python still needs a
    wavelength to calculate the collision x-section in the absence 
    of Burgess-style collision data, so we fill in the wavelength
    from the upper and lower level energies in this case, and issue
    a warning.
    """

    lev = get_levels(ion, nlevels)
    # Next bit is duplicated if I decide to put into a single routine
    x = ch.ion(ion, temperature=1e5)
    # End of duplication

    wavelength = x.Wgfa["wvl"]
    lower = x.Wgfa["lvl1"]
    upper = x.Wgfa["lvl2"]
    gf = x.Wgfa["gf"]
    a = x.Wgfa["avalue"]
    xtab = Table([wavelength, lower, upper, gf, a],
                 names=["Wave", "ll", "ul", "gf", "a"])
    # xtab.info()
    select = []
    gl = []
    gu = []
    el = []
    eu = []
    i = 0
    for one in xtab:
        got_upper = False
        got_lower = False
        for one_level in lev:
            if one_level["lvl"] == one["ll"]:
                got_lower = True
                xgl = one_level["g"]
                xel = one_level["ion_pot"]
            if one_level["lvl"] == one["ul"]:
                got_upper = True
                xgu = one_level["g"]
                xeu = one_level["ion_pot"]
            if got_lower and got_upper:
                select.append(i)
                gl.append(xgl)
                gu.append(xgu)
                el.append(xel)
                eu.append(xeu)
                break
        # print(i,len(xtab))
        i += 1
    # print(select)
    xxtab = xtab[select]
    xxtab["gl"] = gl
    xxtab["gu"] = gu
    xxtab["f"] = xxtab["gf"] / xxtab["gl"]
    xxtab["el"] = x.Ip + el
    xxtab["eu"] = x.Ip + eu
    xxtab["el"].format = "10.6f"
    xxtab["eu"].format = "10.6f"
    xxtab["f"].format = "9.6f"

    xxtab["Dtype"] = "LinMacro"
    xxtab["z"] = lev["Element"][0]
    xxtab["ion"] = lev["Ion"][0]

    # Check for lines that have a Wavelength of 0 and if tis happens fix the
    # wavelegnth using el and eu, but issue a warning when you do this

    for one in xxtab:
        if one["Wave"] == 0:
            one["Wave"] = 12396.1914 / (one["eu"] - one["el"])
            print(
                "Line with ll %d and ul %d is missing wavelength.  Correcting to %.3f using el and eu"
                % (one["ll"], one["ul"], one["Wave"]))

    xxtab["Wave"].format = "10.3f"
    xxxtab = xxtab["Dtype", "z", "ion", "Wave", "f", "gl", "gu", "el", "eu",
                   "ll", "ul"]
    return xxxtab
Ejemplo n.º 23
0
    def __init__(self, ion_name):

        self.ion = ch.ion(ion_name)
        self._levels = None
        self._lines = None
        self._collisions = None
Ejemplo n.º 24
0
def make_phot(ion="c_4"):
    """
    Read a retrieved TopBase file and make a Python-Photon file
    
    Note that althought the TopBase data on Vizier does not use
    astronomical notation, we changed the naming convention
    when we retrieved the files
    """

    x = ch.ion(ion, temperature=1e5)
    z = x.Z
    xion = x.Ion

    fileroot = "p%02d.%02d" % (z, xion)
    try:
        x = open("%s.txt" % fileroot)
        lines = x.readlines()
    except:
        print("Error: %s.txt not found  %s" % fileroot)
        return
    records = []
    for line in lines:
        words = line.split()
        records.append(words)
    f = open("%s.dat" % fileroot, "w")
    # z=int(records[0][0])
    # xion=int(records[0][1])
    i = 1
    num = 0
    xsection = 1
    while i < len(records):
        one_record = records[i]
        # print('test5',one_record)
        if len(one_record) == 4:
            # This is a new x-section
            # if i>1:
            #     print('Number of x-sections %d' % num)
            h = records[i]
            # print(h)
            islp = h[0] + h[1] + h[2]
            if islp == "000":
                break
            ilv = h[3]
            i += 1
            # print(records[i])
            h = records[i]
            npts = int(h[1])
            i += 1
            h = records[i]
            ex = eval(h[0]) * 13.605693009
            if ex == 0:
                xh = records[i + 1]
                ex = eval(xh[0]) * 13.605693009
                print(
                    "Warning: ex=0  for  %d %d %s %s %d - changing to %10.6f" %
                    (z, xion, islp, ilv, npts, ex))
            string = "PhotTopS %d %d %s %s %10.6f %d" % (z, xion, islp, ilv,
                                                         ex, npts)
            # string='PhotTop %d %d  %d %d %d %d' % (z,xion,islp,ilv,ex,npts)
            # print(string)
            f.write("%s\n" % string)
            num = 0
            xsection += 1
        else:
            energy = eval(records[i][0]) * 13.605693009
            xsection = eval(records[i][1]) * 1e-18
            string = "Phot %10.6f %10.6e" % (energy, xsection)
            f.write("%s\n" % string)
            num += 1
        i += 1
        if i == len(records):
            print("Number of x-sections %d" % num)
    f.close()
    return
Ejemplo n.º 25
0
    # array
    c_ori = np.ndarray(shape=(nstat, nte), dtype=np.float64)
    r_ori = np.ndarray(shape=(nstat, nte), dtype=np.float64)

    for ion in range(nstat):
        for ite in range(nte):
            c_ori[ion, ite] = 0
            r_ori[ion, ite] = 0

    # ionization ion loop
    for ion in range(1, nstat):
        ionstr = '{:d}'.format(ion)
        ionname = elemstr + ionstr

        #fe14 = ch.ion('fe_14',temperature=temperature,eDensity=1.e+9,em=1.e+27)
        ionicstruc = ch.ion(ionname, temperature=temperature, eDensity=1.e+9)

        ionicstruc.ionizRate()
        ionizrate = ionicstruc.IonizRate['rate']
        #print(ionname)
        #print('ioniz', ionizrate)

        # save into arraies
        for ite in range(nte):
            c_ori[ion - 1, ite] = ionizrate[ite]
            # test negative value
            if ((ionizrate[ite] < -0.0) or (ionizrate[ite] >= 1.0)):
                print('Negative_ioniz', ion, ite, iatom, ionizrate[ite])
                systime.sleep(40)

    # recombination ion loop
Ejemplo n.º 26
0
def write_phot(ion="c_4"):

    x = ch.ion(ion, temperature=1e5)
    xion = x.Ion
    z = x.Z

    fileroot = "p%02d.%02d" % (x.Z, x.Ion)

    # First strip of the headers of the phot_file
    try:
        phot = open(fileroot + ".dat")
        lines = xx = phot.readlines()
    except:
        print("Error: Could not open %s.dat" % fileroot)

    headers = []
    i = 0
    for one in xx:
        if one.count("PhotTopS"):
            word = one.split()
            word[0] = i
            word[1] = int(word[1])
            word[2] = int(word[2])
            word[3] = int(word[3])
            word[4] = int(word[4])
            word[5] = eval(word[5])
            word[6] = int(word[6])
            headers.append(word)
        i += 1
    phot.close()
    # Now we have a set of records we can make into a table if we are clever
    headers = np.array(headers)
    xxhead = Table(
        headers,
        names=["Row", "Element", "Ion", "islp", "ilv", "e_thresh", "np"],
        dtype=["i", "i", "i", "i", "i", "f", "i"],
    )

    xxhead.write("head.txt",
                 format="ascii.fixed_width_two_line",
                 overwrite=True)
    # xxhead.info()

    # Now find, if we can the parts of the photon file that match what we need

    lev_file = ion + "_levels.dat"
    try:
        lev = ascii.read(lev_file)
    except:
        print("Error: Could not open %s.dat" % lev_file)

    # lev.info()

    # In princple a join of some of this would allow us to find everything we need

    try:
        foo = join(lev,
                   xxhead,
                   keys=["Element", "Ion", "islp", "ilv"],
                   join_type="left")
    except:
        print("Error: join failed")
        xxhead.info()
        lev.info()
        xxhead.write("head.txt",
                     format="ascii.fixed_width_two_line",
                     overwrite=True)
        lev.write("levels.txt",
                  format="ascii.fixed_width_two_line",
                  overwrite=True)
    foo.sort(["Ion", "lvl"])

    foo["delta_e"] = foo["ion_pot"] + foo["e_thresh"]
    foo["delta_e"].format = "8.2f"

    foo.write(ion + "_lev2phot.txt",
              format="ascii.fixed_width_two_line",
              overwrite=True)

    # Now in principle we can write out the PhotFile

    output_file = ion + "_phot.dat"
    f = open(output_file, "w")
    for one in foo:
        if one["e_thresh"] > 0:
            xstring = "PhotMacS  %2d %2d %2d %2d  %10.6f %3d" % (
                z,
                xion,
                one["lvl"],
                1,
                one["e_thresh"],
                one["np"],
            )
            f.write("%s\n" % xstring)
            i = int(one["Row"])
            nphot = int(one["np"])
            j = i + 1
            jstop = j + nphot
            while j < jstop:
                xstring = "PhotMac       13.598430   6.3039999e-18"
                xstring = lines[j]
                xstring = xstring.replace("Phot", "PhotMac")
                f.write(xstring)
                j += 1
    f.close()
Ejemplo n.º 27
0
    #construct list of all partial ionisation stages for each element (i.e. h_1, he_1, he_2, c_1, ...
    ion_names = [
        elem + '_' + str(ionstage + 1)
        for anum, elem in enumerate(elems, start=1) for ionstage in range(anum)
    ]

    # array of temperatures at which to evaluate the collisional ionisation rates
    temp = np.logspace(3, 5, 1000)

    # output temperatures in eV for consistency with other methods in spherical_cloudy
    kB = 1.3806488E-23
    elvolt = 1.60217657E-19
    eV_temp = temp * kB / elvolt

    # construct ChiantiPy objects for each ion under consideration
    ion_objs = [ch.ion(name, temperature=temp) for name in ion_names]

    out_data = np.zeros((len(temp), len(ion_names) + 1))
    out_data[:, 0] = eV_temp

    for i, ion in enumerate(ion_objs):
        print('Getting ' + ion_names[i])
        ion.ionizRate()  # populate field in ChiantiPy object with the rates
        out_data[:, i + 1] = ion.IonizRate['rate']  # extract rates data

    np.savetxt('colioniz_chianti.dat',
               out_data,
               header='temp ' + ' '.join(ion_names))

    #plt.figure()
    #plt.plot(np.log10(out_data[:,0]), np.log10(out_data[:,1:]))
Ejemplo n.º 28
0
def get_collisions(ion="h_1", nlev=20):
    """
    Given a set of levels, get the collision information associatred with these levels.  Note
    that as far as I can determine the scups file does not contain collisionl information 
    for collisional ionization
    
    Currently in Python collisions are tightly tied to the lines that are going to be used
    in a dataset.  The information about line information is used as a mechanism to identify
    the collision x-section.  (This probably dates back to simple atoms, where lines are used
    for radiative transfer and levels are used in calculating densities of upper level states,
    but we don't really have a concept of an integrated atom)
    """
    # Get the collision data

    x = ch.ion(ion, temperature=1e5)
    lower = x.Scups["lvl1"]
    upper = x.Scups["lvl2"]
    de = x.Scups["de"]
    gf = x.Scups["gf"]
    ntemp = x.Scups["ntemp"]
    btemp = x.Scups["btemp"]
    bscups = x.Scups["bscups"]
    lim = x.Scups["lim"]
    ttype = x.Scups["ttype"]
    cups = x.Scups["cups"]

    xtab = Table(
        [lower, upper, de, lim, ntemp, btemp, bscups, ttype, cups],
        names=[
            "ll", "ul", "de", "lim", "ntemp", "btemp", "bscups", "ttype",
            "cups"
        ],
    )

    npossible = 0
    for one in xtab:
        if one["ul"] <= nlev:
            npossible += 1

    xtab.write("T_cups.txt",
               format="ascii.fixed_width_two_line",
               overwrite=True)
    # Get the lines

    linetab = get_lines(ion=ion, nlevels=nlev)
    # linetab.info()
    linetab.write("T_lines.txt",
                  format="ascii.fixed_width_two_line",
                  overwrite=True)

    xxtab = join(xtab, linetab)
    xxtab.write("T_all.txt",
                format="ascii.fixed_width_two_line",
                overwrite=True)
    xxtab["gf"] = xxtab["gl"] * xxtab["f"]

    print(
        "There were %d (of %d) collision x-sections with nlev <= %d, and %d that matched %d lines"
        % (npossible, len(xtab), nlev, len(xxtab), len(linetab)))

    # xtab=Table([lower,upper,gf,ntemp,btemp,bscups],names=['ll','de','ul','gf','ntemp','btemp','bscups'])
    # xxtab.info()
    xout = open(ion + "_upsilon.dat", "w")
    for one in xxtab:
        # print(one)
        xstring = "CSTREN Line %3d %3d %10.3f %9.6f %2d %2d  %10.6f %10.6f " % (
            one["z"],
            one["ion"],
            one["Wave"],
            one["f"],
            one["gl"],
            one["gu"],
            one["el"],
            one["eu"],
        )
        xstring = xstring + "%3d %3d %3d %3d %10.3e %10.3e %10.3e %3d %3d %10.3e" % (
            one["ll"],
            one["ul"],
            one["ll"],
            one["ul"],
            one["de"],
            one["gf"],
            one["lim"],
            one["ntemp"],
            one["ttype"],
            one["cups"],
        )

        # print(xstring)
        xout.write("%s\n" % xstring)

        xstring = "SCT    "
        for one_temp in one["btemp"]:
            xstring = xstring + (" %10.3e" % one_temp)
        xout.write("%s\n" % xstring)

        xstring = "SCUPS  "
        for one_bscup in one["bscups"]:
            xstring = xstring + (" %10.3e" % one_bscup)
        xout.write("%s\n" % xstring)

    xout.close()
    return xxtab