# Database Models in carsus¶

## Atomic models in carsus¶

### Introduction¶

Carsus uses sqlalchemy to associate (experimental) data about real objects, such as atoms, with tables in a database. This allows us to store all data in one big database but we can use it as if it were simple python objects. Additionally, operations like filtering the data are performed on the database instead of in python which is a lot better for the performance.

At the core of this system are the database models. These are python classes with special class attributes that are mapped to database columns by sqlalchemy. In the database, each class has its own table and instances of the class represent one specific row of that table. All models have to inherit from Base which is defined in carsus.model.meta. Each model has a “Primary Key” which has to be unique for each object and is used to identify it. Typically this is an integer but it is also possible to use a combination of multiple values to form the primary key (see IonQuantity for example). If the primary key is a single integer, it should be called ‘id’.

Attributes of instances are declared as instances of Column which is a special class attribute pointing to a column in a table. Relationships between models are defined with relationship() linking two instances of an object together where usually one column points to the primary key of another table. Defining the relationships is important so sqlalchemy can automatically join the models together if a join operation is added to the query.

We have several types of models for the atomic data. First, we have general models, like Atom and Ion. These are universal and independent of the source of the data. They serve as anchors for datasource dependent quantities to be linked against. These are not universal, like for example the IonizationEnergy, but come from sources such as NIST. To easily allow the data from different sources for the same quantity in the database, they are linked to a source. This is very important because when extracting the data, we always have to specify the source of the data we want to extract.

### Classes¶

class carsus.model.atomic.Atom(**kwargs)

Bases: sqlalchemy.ext.declarative.api.Base

Model describing a simple Atom.

atomic_number

Atomic number of the Atom

class carsus.model.atomic.AtomQuantity(**kwargs)

Bases: carsus.model.meta.schema.QuantityMixin, sqlalchemy.ext.declarative.api.Base

Base class for all quantities of an Atom. Mixes in the QuantityMixin to expose the auantity interface.

atom_qty_id

Primary Key

atomic_number

ForeignKey linking a AtomQuantity to an Atom

data_source

Relationship to the DataSource

data_source_id

ID (in the database) of the DataSource

class carsus.model.atomic.AtomWeight(**kwargs)

Weight of an Atom in atomic units [‘u’].

data_source

Relationship to the DataSource

data_source_id

ID (in the database) of the DataSource

unit = Unit("u")
class carsus.model.atomic.Ion(**kwargs)

Bases: carsus.model.meta.orm.UniqueMixin, sqlalchemy.ext.declarative.api.Base

Model describing an Ion. Inherits the UniqueMixin to guarantee no duplicates.

atom

Relationship to Atom

atomic_number

ForeignKey linking an Ion to an Atom

ion_charge

Charge of the ion

ionization_energies

Relationship to IonizationEnergy

levels

Relationship to Level

class carsus.model.atomic.IonQuantity(**kwargs)

Bases: carsus.model.meta.schema.QuantityMixin, sqlalchemy.ext.declarative.api.Base

Base class for all quantities of an Ion. Mixes in the QuantityMixin to expose the auantity interface.

atomic_number

data_source

Relationship to the DataSource

data_source_id

ID (in the database) of the DataSource

ion_charge

ion_qty_id

Primary Key

class carsus.model.atomic.IonizationEnergy(**kwargs)

Ionization energy of an Ion in electron volt [eV]. foo

data_source

Relationship to the DataSource

data_source_id

ID (in the database) of the DataSource

unit = Unit("eV")
class carsus.model.atomic.Level(**kwargs)

Bases: sqlalchemy.ext.declarative.api.Base

Level of an Ion.

J

total angular momentum

L

total orbital angular momentum

atomic_number

configuration

Configuration of the level

data_source_id

Id of the datasource of this level

ion_charge

level_id

Primary Key

level_index

Index of this level from its data source

parity

Parity 0 - even, 1 - odd

spin_multiplicity

spin_multiplicity 2*S+1, where S is total spin

class carsus.model.atomic.LevelQuantity(**kwargs)

Bases: carsus.model.meta.schema.QuantityMixin, sqlalchemy.ext.declarative.api.Base

Base class for all quantities of a level. Mixes in the QuantityMixin to expose the auantity interface.

data_source

Relationship to the DataSource

data_source_id

ID (in the database) of the DataSource

class carsus.model.atomic.LevelEnergy(**kwargs)
data_source

Relationship to the DataSource

data_source_id

ID (in the database) of the DataSource

unit = Unit("eV")
class carsus.model.atomic.LineQuantity(**kwargs)

Bases: carsus.model.meta.schema.QuantityMixin, sqlalchemy.ext.declarative.api.Base

Base class for all quantities of a line. Mixes in the QuantityMixin to expose the auantity interface.

data_source

Relationship to the DataSource

data_source_id

ID (in the database) of the DataSource

class carsus.model.atomic.LineWavelength(**kwargs)
data_source

Relationship to the DataSource

data_source_id

ID (in the database) of the DataSource

unit = Unit("Angstrom")
class carsus.model.atomic.LineAValue(**kwargs)
data_source

Relationship to the DataSource

data_source_id

ID (in the database) of the DataSource

class carsus.model.atomic.LineGFValue(**kwargs)
data_source

Relationship to the DataSource

data_source_id

ID (in the database) of the DataSource

class carsus.model.atomic.ECollisionQuantity(**kwargs)

Bases: carsus.model.meta.schema.QuantityMixin, sqlalchemy.ext.declarative.api.Base

Base class for all quantities of an electron collision. Mixes in the QuantityMixin to expose the auantity interface.

data_source

Relationship to the DataSource

data_source_id

ID (in the database) of the DataSource

class carsus.model.atomic.ECollisionEnergy(**kwargs)
data_source

Relationship to the DataSource

data_source_id

ID (in the database) of the DataSource

unit = Unit("eV")
class carsus.model.atomic.ECollisionGFValue(**kwargs)
data_source

Relationship to the DataSource

data_source_id

ID (in the database) of the DataSource

class carsus.model.atomic.DataSource(**kwargs)

Bases: carsus.model.meta.orm.UniqueMixin, sqlalchemy.ext.declarative.api.Base

## Base classes and helpers¶

Fundamental units like declarative_base

class carsus.model.meta.base.Base(**kwargs)
carsus.model.meta.base.setup(url, **kwargs)

Creates a configured “Session” class and returns its instance

Database schema generation/definition helpers

class carsus.model.meta.schema.DataSourceMixin

Mixin that marks a model as datasource dependent by adding data_source_id and data_source class attributes.

class carsus.model.meta.schema.IonListMixin

Mixin for creating temporary tables for selecting ions from a list of ions.

Because SQLite doesn’t support composite IN expressions (you can’t do WHERE atomic_number, ion_charge in some_list_of_ions) temporary tables are needed for selecting ions.

This is needed because of ions not having a proper primary key but being linked to an atom. FIXME?

class carsus.model.meta.schema.QuantityMixin

Mixin that marks a database model as a physical quantity.

method = Column(None, String(length=15), table=None)

experimental or theoretical data

uncert = Column(None, Float(), table=None)

uncertainty of the measurement

unit = Unit(dimensionless)

Unit of data

Object-relational mapping helpers

class carsus.model.meta.orm.UniqueMixin

Unique object mixin.

Allows an object to be returned or created as needed based on criterion.

carsus.model.meta.orm.yield_limit(qry, pk_attr, maxrq=100)

Specialized windowed query generator (using LIMIT/OFFSET) This recipe is to select through a large number of rows thats too large to fetch at once. The technique depends on the primary key of the FROM clause being an integer value, and selects items using LIMIT.

The recipe is taken from https://bitbucket.org/zzzeek/sqlalchemy/wiki/UsageRecipes/WindowedRangeQuery