Quick Start

This short tutorial will demonstrate some of the capabilities of ChiantiPy and the CHIANTI database. It assumes that you know what the CHIANTI database provides and why you want to use it. The current implementation in Version 0.2 mainly provides access to methods concerned with single ions. An ion such as Fe XIV is specified by the string ‘fe_14’, in the usual CHIANTI notation.

Bring up a Python session (using > Python -i ), or better yet, an IPython session

import chianti.core as ch
from numpy import *

What we will really be interested in are various properties of the Fe XIV emissivities as a function of temperature and density. So, let’s define a numpy array of temperatures

t = 10.**(5.8 + 0.05*arange(21.))

In ChiantiPy, temperatures are currently given in degrees Kelvin and densities as the number electron density per cubic cm. Then, construct fe14 as would be typically done

fe14 = ch.ion('fe_14', temperature=t, eDensity=1.e+9)

note that eDensity is the new keyword for electron density

Level populations


produces a matplotlib plot window were the population of the top 10 (the default) levels are plotted as a function of temperature.


If the level populations had not already been calculated, popPlot() would have invoked the populate() method which calculates the level populations and stores them in the Population dictionary, with keys = [‘protonDensity’, ‘population’, ‘temperature’, ‘density’].

A ChiantiPy Convention

Classes and function of ChiantiPy start with lower case letters. Data attached to the instantiation of a class will start with a capital letter. For example,

fe14.populate() creates fe14.Population containing the level population information

fe14.emiss() creates fe14.Emiss containing the line emissivity information

fe14.intensity() creates fe14.Intensity containing the line intensity information that includes the elemental abundance and the ionization equilibrium

fe14.spectrum() creates fe14.Spectrum contain the line and continuum spectrum information


fe14.emissPlot(wvlRange=[210., 220.])

will plot the emissivities for the top (default = 10) lines in the specified wavelength range. Since there are 21 temperature involved, a single temperature is selected (21/2 = 10). Otherwise,

fe14.emissPlot(index=2, wvlRange=[210., 220.])

plots the emissivities for a temperature = t[2] = 7.9e+5, in this case. And, by specifying relative = 1, the emissivities will be plotted relative to the strongest line.

fe14.emissList(wvlRange=[200,220], index=10, relative=1)

gives the following terminal output:

using index =    10 specifying temperature =    2.00e+06


lvl1  lvl2         lower                       upper                  Wvl(A)   Emissivity     A value  Obs
  1    11              3s2.3p 2P0.5 - 3s2.3d 2D1.5                   211.317    1.000e+00     3.81e+10 Y
  4    27              3s.3p2 4P1.5 - 3s.3p(3P).3d 4P1.5             212.125    5.236e-03     2.21e+10 Y
  3    24              3s.3p2 4P0.5 - 3s.3p(3P).3d 4D0.5             213.196    6.637e-03     4.26e+10 Y
137   261              3s2.4d 2D1.5 - 3s2.5p 2P0.5                   213.388    4.848e-03     1.87e+10 N
  3    23              3s.3p2 4P0.5 - 3s.3p(3P).3d 4D1.5             213.882    1.189e-02     2.97e+10 Y
  5    28              3s.3p2 4P2.5 - 3s.3p(3P).3d 4D2.5             216.579    8.566e-03     2.83e+10 Y
  5    25              3s.3p2 4P2.5 - 3s.3p(3P).3d 4D3.5             216.917    1.223e-02     4.29e+10 Y
  7    32              3s.3p2 2D2.5 - 3s.3p(3P).3d 2F3.5             218.177    2.306e-02     1.70e+10 Y
  4    22              3s.3p2 4P1.5 - 3s.3p(3P).3d 4P2.5             218.572    1.918e-02     2.65e+10 Y
  2    12              3s2.3p 2P1.5 - 3s2.3d 2D2.5                   219.131    2.488e-01     4.27e+10 Y


optionally, an output file could also be created by setting the keyword outFile to the name of the desired name

G(n,T) function

fe14.gofnt(wvlRange=[210., 220.],top=3)

brings up a matplotlib plot window which shows the emissivities of the top (strongest) 3 lines in the wavelength region from 210 to 220 Angstroms.


quickly followed by a dialog where the line(s) of interest can be specified


and finally a plot of the G(n,T) function for the specified lines(s).


The G(n,T) calculation is stored in the Gofnt dictionary, with keys = [‘gofnt’, ‘temperature’, ‘density’]

Intensity and IntensityRatios


gives the following terminal output:

using index =    10 specifying temperature =    2.00e+06


  Ion  lvl1  lvl2                     lower - upper                           Wvl(A)    Intensity      A value Obs
fe_14     1    11              3s2.3p 2P0.5 - 3s2.3d 2D1.5                  211.3172    2.336e-25     3.81e+10 Y
fe_14     4    27              3s.3p2 4P1.5 - 3s.3p(3P).3d 4P1.5            212.1255    5.355e-28     2.21e+10 Y
fe_14     4    28              3s.3p2 4P1.5 - 3s.3p(3P).3d 4D2.5            212.1682    4.039e-28     1.15e+10 Y
fe_14     3    24              3s.3p2 4P0.5 - 3s.3p(3P).3d 4D0.5            213.1955    8.073e-28     4.26e+10 Y
fe_14     3    23              3s.3p2 4P0.5 - 3s.3p(3P).3d 4D1.5            213.8822    1.393e-27     2.97e+10 Y
fe_14     5    28              3s.3p2 4P2.5 - 3s.3p(3P).3d 4D2.5            216.5786    9.736e-28     2.83e+10 Y
fe_14     5    25              3s.3p2 4P2.5 - 3s.3p(3P).3d 4D3.5            216.9173    1.730e-27     4.29e+10 Y
fe_14     7    32              3s.3p2 2D2.5 - 3s.3p(3P).3d 2F3.5            218.1767    3.734e-27     1.70e+10 Y
fe_14     4    22              3s.3p2 4P1.5 - 3s.3p(3P).3d 4P2.5            218.5725    2.391e-27     2.65e+10 Y
fe_14     2    12              3s2.3p 2P1.5 - 3s2.3d 2D2.5                  219.1305    5.077e-26     4.27e+10 Y

fe14.intensityRatio(wvlRange=[210., 225.])

this brings up a plot showing the relative emissivities on the Fe XIV lines


following by a dialog where you can selector the numerator(s) and denominator(s) of the desired intensity ratio


so the specified ratio is then plotted


if previously, we had done

d = 10.**(6. + 0.1*arange(61))
fe14 = ch.ion('fe_14', temperature = 2.e+6, eDensity = d)

then the plot of relative intensities vs density would appear


the same numerator/denominator selector dialog would come up and when 2 or more lines are selected, the intensity ratio versus density appears.


to obtain ratios of lines widely separated in wavelength, the wvlRanges keyword can be used:

fe12 = ch.ion('fe_12', temperature=t, eDensity=1.e+9

to save the intensity ratios to a file:


and the following output to the terminal:

saving ratio to filename = fe_14_218.1767-_211.3172.rat



saves it to the file mydata.txt

Spectra of a single ion

fe14 = ch.ion('fe_14', temperature = 2.e+6, eDensity = 1.e+9)
wvl = wvl=200. + 0.125*arange(801)
plot(wvl, fe14.Spectrum['intensity'])

this will calculate the spectrum of fe_14 over the specified wavelength range and filter it with the default filter which is a gaussian (filters.gaussianR) with a ‘resolving power’ of 1000 which gives a gaussian width of wvl/1000.


other filters available in chianti.filters include a boxcar filter and a gaussian filter where the width can be specified directly

import chianti.filters as chfilters

calculates the spectrum of fe_14 for a gaussian filter with a width of 0.4 Angstroms.


In ChiantiPy 0.6, the label keyword has been added to the ion.spectrum method, and also to the other various spectral classes.

t = 10.**(5.8 + 0.05*arange(21.))


the output to the console is > 2.00e+06

fe14 = ch.ion('fe_14', temperature=t, eDensity=1.e+9)







produces a plot with the spectra for different gaussian widths compared


Free-free and free-bound continuum

The module continuum provides the ability to calculate the free-free and free-bound spectrum for a large number of individual ions.

temperature = 2.e+7
c = c h.continuum('fe_25', temperature = temperature)
wvl = 1. + 0.002*arange(4501)
plot(wvl, c.FreeFree['rate'])
plot(wvl, c.FreeBound['rate'])



In the continuum calculations, the specified ion, Fe XXV in this case, is the target ion for the free-free calculation. For the free-bound calculation, specified ion is also the target ion. In this case, the radiative recombination spectrum of Fe XXV recombining to form Fe XXIV is returned.

The multi-ion class bunch

The multi-ion class bunch [new in v0.6] inherits a number of the same methods inherited by the ion class, for example intensityList,*intensityRatio*, and intensityRatioSave. As a short demonstration of its usefulness, Widing and Feldman (1989, ApJ, 344, 1046) used line ratios of Mg VI and Ne VI as diagnostics of elemental abundance variations in the solar atmosphere. For that to be accurate, it is necessary that the lines of the two ions have the same temperature response.

t = 10.**(5.0+0.05*arange(21))

then the intensity of the top 7 lines as a function of temperature are displayed


then the usual selection widget comes up and the following ratio is selected and displayed


there seems to be a significant temperature dependence to the ratio, even though both are formed near 4.e+5 K.

A new keyword argument keepIons has been added in v0.6 to the bunch and the 3 spectrum classes.

bnch2=ch.bunch(t, 1.e+9, wvlRange=[300.,500.], ionList=['ne_6','mg_6'], abundanceName='unity', keepIons=1)
plot(wvl, bnch2.Spectrum['intensity'][12])
title('Temperature = %10.2e for t[12]'%(t[12]))



the benefit of setting the keepIons keyword is that the ion instances are kept in an attribute IonInstances which is a dictionary of all the ion instances in the selection and it is not necessary to repeat the intensity calculations to convolve the spectrum.


> [‘mg_6’, ‘ne_6’]

Spectra of multiple ions and continuum

the spectrum for selection of all of the ions in the CHIANTI database can also be calculated. There are 3 spectral classes.

  1. spectrum - the single processor implementation that can be used anywhere
  2. mspectrum - uses the Python multiprocessing class and cannot be used in a IPython qtconsole or notebook
  3. ipymspectrum [new in v0.6] - uses the IPython parallel class and can be used in a IPython qtconsole or notebook
temperature = [1.e+6, 2.e+6]
density = 1.e+9
wvl = 200. + 0.05*arange(2001)
emeasure = [1.e+25 ,1.e+25]
s = ch.spectrum(temperature, density, wvl, filter = (filters.gaussian,.2), em = emeasure, doContinuum=0, minAbund=1.e-4)
plot(wvl, s.Spectrum['integrated'])
plot(wvl, s.Spectrum['intensity'][0]*emeasure[0])
plot(wvl, s.Spectrum['intensity'][1]*emeasure[1])



the integrated spectrum is formed by multiplying each spectrum by the value of em (‘as in emission measure’) and summing them. Note that even though a value is specified for em, only the values of s.Spectrum[‘integrated’] have been multiplied by em. Also, the filter is not applied to the continuum. This spectrum was created with CHIANTI database version 7.1 and ChiantiPy version 0.5.2 using the following default values:

for akey in
   print(' %10s - %s'%(akey,[akey]))

wavelength - angstrom
       gui - False
 ioneqfile - chianti
 abundfile - sun_photospheric_1998_grevesse
      flux - energy

One can also use a different abundance file than the default by specifying the abundanceName keyword. For example, abundanceName = ‘cosmic_1973_allen.abund’. If the specified file is not found in XUVTOP/abundance, then a widget will pop up and one can select the abundance file from a list.

It is also possible to specify a selection of ions by means of the ionList keyword, for example, ionList=[‘fe_11’,’fe_12’,’fe_13’] or with the elementList keyword, for example, elementList=[‘mg’,’si’]

For a minAbund of 1.e-4, 20 ions were calculated in 21 s. If the keyword argument minAbund were set to 1.e-5, then the spectra of 80 ions would be calculated. This would take about 8 min. on a single processor running at about 3 GHz.

s2 = ch.spectrum(temperature, density, wvl, filter = (filters.gaussian,.2), em = emeasure, doContinuum=0, keepIons=1, elementList=['si'], minAbund=1.e-4)
ylabel(r'erg cm$^{-2}$ s$^{-1}$ sr$^{-1} \AA^{-1}$')
ylabel(r'erg cm$^{-2}$ s$^{-1}$ sr$^{-1} \AA^{-1}$')
xlabel(r'Wavelength ($\AA$)')
title('Si IX')



Because keepIons has been set, the ion instances of all of the ions are maintained in the s2.IonInstances dictionary. It is then possible to compare the spectrum of all of the ions with the spectrum of a single ion.

temperature = 1.e+7
wvl = 10. + 0.005*arange(2001)
s = ch.spectrum(temperature, density, wvl, filter = (chfilters.gaussian,.015))
plot(wvl, s.Spectrum['intensity'])



this includes free-free, free-bound and line radiation. The continuum intensities are also available:

temperature = 2.e+7
density = 1.e+9
wvl = 1. + 0.002*arange(4501)
emeasure = 1.e+25
import chianti.filters as chfilters
s = ch.spectrum(temperature density, wvl, em = emeasure, filter = (chfilters.gaussian,.005))


temperature = 2.e+7
density = 1.e+9
wvl = 1.84 + 0.0001*arange(601)
import chianti.filters as chfilters
s = ch.spectrum(temperature, density ,wvl, filter = (chfilters.gaussian,.0003), doContinuum=0)



Calculations with the Spectrum module can be time consuming. One way to control the length of time the calculations take is to limit the number of ions with the ionList keyword and to avoid the continuum calculations by setting the doContinuum keyword to 0 or False. Another way to control the length of time the calculations take is with the minAbund keyword. It sets the minimum elemental abundance that an element can have for its spectra to be calculated. The default value is set include all elements. Some usefull values of minAbund are:

minAbund = 1.e-4, will include H, He, C, O, Ne minAbund = 2.e-5 adds N, Mg, Si, S, Fe minAbund = 1.e-6 adds Na, Al, Ar, Ca, Ni

Calculations with multiple processors

Another way to speed up calculations is to use the mspectrum class which uses multiple cores on your local computer. It requires the Python multiprocessing module which is available with Python versions 2.6 and later. mspectrum is called in the same way as spectrum but you can specify the number of cores with the proc keyword. The default is 3 but it will not use more cores than are available on your machine. However, mspectrum cannot be used in the IPython Qtconsole or the IPython notebook. For example,

s = ch.mspectrum(temperature, density ,wvl, em=emeasure, filter = (chfilters.gaussian,.005), proc=2)

ipymspectrum has been introduced in v0.6.0 to enable parallel processing on multiple processors. It is invoked like all of the spectrum classes. It is necessary to go into a console and start up a given number of engines. The following assumes that you have a notebook profile and will use this in a noteook and will start 3 engines.

>  ipcluster start --profile=notebook  --n=3

Radiative loss rate

the radiative loss rate can be calculated as a function of temperature and density:

temp = 10.**(4.+0.05*arange(81)) rl = ch.radLoss(temp, 1.e+4, minAbund=2.e-5) rl.radLossPlot()


Get ChiantiPy at Fast, secure and Free Open Source software downloads