Quickstart

This notebook provides a quick introduction in how to use Carsus.

Prerequisites:

  • Install carsus (preferably as a git repository)

  • Install ChiantiPy (from source or pip, both versions work)

  • Install chiantipy and set the environmentvariable XUVTOP = /path/to/chianti/root

  • We highly recommend installing the carsus-db repository as it includes the files of several sources that cannot easily be downloaded.

Creating a database

To start working with a database you need to initialize it. This requires a url, for example sqlite:///path/to/example.db. In this quickstart, we’ll use a in-memory sqlite database, so we leave the url empty:

[1]:
from carsus import init_db
session = init_db()
Initializing the database at sqlite://
Ingesting basic atomic data

Now, we have a SQLAlchemy Session object named session. We can use session to make simple queries. As you can see from the output, “basic atomic data” has been ingested into our database. Let’s examine it:

[2]:
from carsus.model import Atom
print('Number of Atoms in the database: {}'.format(session.query(Atom).count()))
si = session.query(Atom).get(14)
print("Symbol: {}, atomic_number: {}, name: {}".format(si.symbol, si.atomic_number, si.name))
Number of Atoms in the database: 118
Symbol: Si, atomic_number: 14, name: Silicon

So, our database already contains basic information about atoms. But this informaition has not been commited to the database yet. It is always your responsibility to commit data!

[3]:
session.commit()

To store more interesting data we are going to use ingesters. For each data source supported by Carsus there is a corresponding ingester class. For example, let’s ingest atomic weights from the NIST Atomic Weights and Isotopic Compositions database:

[4]:
from carsus.io import NISTWeightsCompIngester
weightscomp_ingester = NISTWeightsCompIngester(session)
weightscomp_ingester.ingest()
session.commit()
 found PyQt4 widgets
 using PyQt4 widgets
Downloading data from the NIST Atomic Weights and Isotopic Compositions database.
Ingesting atomic weights from nist

And now atoms have atomic weights:

[5]:
print si.weights
[<Quantity: 28.085 u>]

Other ingesters are just the same, but they often take specific arguments:

[6]:
from carsus.io import GFALLIngester, NISTIonizationEnergiesIngester

# Ingest ionization energies and ground levels from the NIST Atomic Spectra Database
ioniz_energies_ingester = NISTIonizationEnergiesIngester(session, spectra="Si")
ioniz_energies_ingester.ingest(ionization_energies=True, ground_levels=True)

# Ingest levels and lines from the Kurucz Database
gfall_ingester = GFALLIngester(session, fname="gfall.dat", ions="Si 1-2")
gfall_ingester.ingest(levels=True, lines=True)
session.commit()
Downloading ionization energies from the NIST Atomic Spectra Database
/media/data/projects/tardis/carsus/carsus/io/nist/ionization.py:88: ParserWarning: Falling back to the 'python' engine because the 'c' engine does not support skipfooter; you can avoid this warning by specifying engine='python'.
  usecols=range(5), names=column_names, skiprows=3, skipfooter=1)
Ingesting ionization energies from nist-asd
Ingesting ground levels from nist-asd
Ingesting levels from ku_latest
Ingesting levels for Si 1
Ingesting levels for Si 2
Ingesting lines from ku_latest
Ingesting lines for Si 1
Ingesting lines for Si 2

Now we have ionization energies, levels and lines for ions of Si (Note: Si 1 = Si II, Si 2 = Si III, etc.). You should always use Arabic numerals when specifying ions:

[7]:
from carsus.model import Ion
si_1 = session.query(Ion).get((14,1))
print len(si_1.levels)
166

This is it! Now you can explore the data you have in your database or create output hdf files.

Creating output HDFStores

Once you have a database it is very easy to create atomic data files for TARDIS. To do this you need to use a special class called AtomData. The class takes session as its first argument; other important parameters are selected_atoms and chianti_ions. Only data for selected_atoms will be stored in the output DataFrames and levels and lines for chianti_ions will be taken from the data source with the same name. Let’s create an AtomData instance:

[8]:
from carsus.io import AtomData
atom_data = AtomData(session, selected_atoms="Si")

The output DataFrames can be easily accessed as “prepared” attributes of atom_data:

[9]:
print atom_data.atom_masses_prepared
              symbol     name    mass
atomic_number
14                Si  Silicon  28.085
[10]:
print atom_data.levels_prepared.loc[:10]
    atomic_number  ion_number  level_number    energy  g  metastable
0              14           0             0  0.000000  1        True
1              14           1             0  0.000000  2        True
2              14           1             1  0.035613  4        True
3              14           1             2  5.309535  2        True
4              14           1             3  5.322966  4        True
5              14           1             4  5.344699  6        True
6              14           1             5  6.857485  4       False
7              14           1             6  6.859448  6       False
8              14           1             7  8.121023  2       False
9              14           1             8  9.505292  2       False
10             14           1             9  9.836720  4       False
[11]:
print atom_data.macro_atom_prepared.loc[:10]
    atomic_number  ion_number  source_level_number  destination_level_number  \
0              14           1                    0                        71
1              14           1                    0                        66
2              14           1                    0                        57
3              14           1                    0                        56
4              14           1                    0                        46
5              14           1                    0                        45
6              14           1                    0                        30
7              14           1                    0                        29
8              14           1                    0                        21
9              14           1                    0                        20
10             14           1                    0                        18

    transition_type  transition_probability  transition_line_id
0                 1                     0.0                   9
1                 1                     0.0                  10
2                 1                     0.0                  14
3                 1                     0.0                  19
4                 1                     0.0                  24
5                 1                     0.0                  27
6                 1                     0.0                  29
7                 1                     0.0                  32
8                 1                     0.0                  56
9                 1                     0.0                  62
10                1                     0.0                  76

To create an HDFStore you need to use the to_hdf() method. You should specify every DataFrame that you want to be stored:

[12]:
atom_data.to_hdf("example_store.h5", store_atom_masses=True, store_ionization_energies=True,
                store_levels=True, store_lines=True, store_macro_atom=True)
Signing AtomData with MD5 and UUID1

You are done! Now you can use the created HDFStore to run TARDIS simulations.