<commit_before># atomic model

import os
import logging
import tardis
import numpy as np
import pandas as pd

from scipy import interpolate
from collections import OrderedDict


class AtomDataNotPreparedError(Exception):
    pass


logger = logging.getLogger(__name__)

tardis_dir = os.path.dirname(os.path.realpath(tardis.__file__))


def data_path(fname):
    return os.path.join(tardis_dir, 'data', fname)


def tests_data_path(fname):
    return os.path.join(tardis_dir, 'tests', 'data', fname)


default_atom_h5_path = data_path('atom_data.h5')

atomic_symbols_data = np.recfromtxt(data_path('atomic_symbols.dat'),
                                    names=['atomic_number', 'symbol'])

symbol2atomic_number = OrderedDict(zip(atomic_symbols_data['symbol'],
                                       atomic_symbols_data['atomic_number']))
atomic_number2symbol = OrderedDict(atomic_symbols_data)


class AtomData(object):
    """
    Class for storing atomic data

    Parameters
    ----------
    atom_data: pandas.DataFrame
        A DataFrame containing the *basic atomic data* with:
            index: atomic_number;
            columns: symbol, name, mass[CGS].

    ionization_data: pandas.DataFrame
        A DataFrame containing the *ionization data* with:
            index: atomic_number, ion_number;
            columns: ionization_energy[CGS].

       It is important to note here is that `ion_number` describes the *final ion state*
            e.g. H I - H II is described with ion=1

    levels: pandas.DataFrame
        A DataFrame containing the *levels data* with:
            index: no index;
            columns: atomic_number, ion_number, level_number, energy[CGS], g[1], metastable.

    lines: pandas.DataFrame
        A DataFrame containing the *lines data* with:
            index: no index;
            columns: line_id, atomic_number, ion_number, level_number_lower, level_number_upper,
                wavelength[angstrom], wavelength_cm[CGS], nu[Hz], f_lu[1], f_ul[1], B_ul[?], B_ul[?], A_ul[1/s].

    macro_atom_data:
        A DataFrame containing the *macro atom data* with:
            index: no_index;
            columns: atomic_number, ion_number, source_level_number, destination_level_number,
                transition_line_id, transition_type, transition_probability;

    macro_atom_references:
        A DataFrame containing  the *macro atom references* with:
            index: no_index;
            columns: atomic_number, ion_number, source_level_number, count_down, count_up, count_total.

        Refer to the docs: http://tardis.readthedocs.io/en/latest/physics/plasma/macroatom.html

    collision_data: (pandas.DataFrame, np.array)
        A DataFrame containing the *electron collisions data* with:
            index: atomic_number, ion_number, level_number_lower, level_number_upper;
            columns: e_col_id, delta_e, g_ratio, c_ul;

    collision_data_temperatures: np.array
        An array with the collision temperatures.

    zeta_data: ?
    synpp_refs: ?
    ion_cx_tx_data: ?
    ion_cx_sp_data: ?

    Attributes
    -------------
    prepared: bool

    atom_data: pandas.DataFrame
    ionization_data: pandas.DataFrame
    macro_atom_data_all: pandas.DataFrame
    macro_atom_references_all: pandas.DataFrame
    collision_data: pandas.DataFrame
    collision_data_temperatures: numpy.array
    zeta_data: pandas.DataFrame
    synpp_refs: pandas.DataFrame
    ion_cx_tx_data: pandas.DataFrame
    ion_cx_sp_data: pandas.DataFrame
    symbol2atomic_number: OrderedDict
    atomic_number2symbol OrderedDict

    Methods
    --------
    from_hdf
    prepare_atom_data

    Notes
    ------
    1. The units of some columns are given in the square brackets. They are **NOT** the parts of columns' names!

    """

    hdf_names = ["atom_data", "ionization_data", "levels", "lines",
                 "macro_atom_data", "macro_atom_references", "zeta_data", "collision_data",
                 "collision_data_temperatures", "synpp_refs", "ion_cx_th_data", "ion_cx_sp_data"]

    @classmethod
    def from_hdf(cls, fname=None):
        """
        Function to read all the atom data from the special Carsus HDFStore file.

        Parameters
        ----------

        fname: str, optional
            The path to the HDFStore file. If set to `None` the default file with limited atomic_data
            shipped with TARDIS will be used. For more complex atomic data please contact the authors.
            (default: None)
        """

        if fname is None:
            fname = default_atom_h5_path

        if not os.path.exists(fname):
            raise ValueError("Supplied Atomic Model Database %s does not exists" % fname)

        dataframes = dict()
        nonavailable = list()

        with pd.HDFStore(fname) as store:
            for name in cls.hdf_names:
                try:
                    dataframes[name] = store[name]
                except KeyError:
                    nonavailable.append(name)

            atom_data = cls(**dataframes)

            atom_data.uuid1 = store.root._v_attrs['uuid1']
            atom_data.md5 = store.root._v_attrs['md5']

            try:
                atom_data.version = store.root._v_attrs['database_version']
            except KeyError:
                atom_data.version = None

            # ToDo: strore data sources as attributes in carsus

            logger.info(
                "Read Atom Data with UUID={0} and MD5={1}. "
                "Not found: {2}".format(atom_data.uuid1, atom_data.md5, ", ".join(nonavailable))
            )


        return atom_data

    def __init__(self, atom_data, ionization_data, levels=None, lines=None,
                 macro_atom_data=None, macro_atom_references=None, zeta_data=None,<commit_msg>Use try..except to read md5 and uuid1<commit_after># atomic model

import os
import logging
import tardis
import numpy as np
import pandas as pd

from scipy import interpolate
from collections import OrderedDict


class AtomDataNotPreparedError(Exception):
    pass


logger = logging.getLogger(__name__)

tardis_dir = os.path.dirname(os.path.realpath(tardis.__file__))


def data_path(fname):
    return os.path.join(tardis_dir, 'data', fname)


def tests_data_path(fname):
    return os.path.join(tardis_dir, 'tests', 'data', fname)


default_atom_h5_path = data_path('atom_data.h5')

atomic_symbols_data = np.recfromtxt(data_path('atomic_symbols.dat'),
                                    names=['atomic_number', 'symbol'])

symbol2atomic_number = OrderedDict(zip(atomic_symbols_data['symbol'],
                                       atomic_symbols_data['atomic_number']))
atomic_number2symbol = OrderedDict(atomic_symbols_data)


class AtomData(object):
    """
    Class for storing atomic data

    Parameters
    ----------
    atom_data: pandas.DataFrame
        A DataFrame containing the *basic atomic data* with:
            index: atomic_number;
            columns: symbol, name, mass[CGS].

    ionization_data: pandas.DataFrame
        A DataFrame containing the *ionization data* with:
            index: atomic_number, ion_number;
            columns: ionization_energy[CGS].

       It is important to note here is that `ion_number` describes the *final ion state*
            e.g. H I - H II is described with ion=1

    levels: pandas.DataFrame
        A DataFrame containing the *levels data* with:
            index: no index;
            columns: atomic_number, ion_number, level_number, energy[CGS], g[1], metastable.

    lines: pandas.DataFrame
        A DataFrame containing the *lines data* with:
            index: no index;
            columns: line_id, atomic_number, ion_number, level_number_lower, level_number_upper,
                wavelength[angstrom], wavelength_cm[CGS], nu[Hz], f_lu[1], f_ul[1], B_ul[?], B_ul[?], A_ul[1/s].

    macro_atom_data:
        A DataFrame containing the *macro atom data* with:
            index: no_index;
            columns: atomic_number, ion_number, source_level_number, destination_level_number,
                transition_line_id, transition_type, transition_probability;

    macro_atom_references:
        A DataFrame containing  the *macro atom references* with:
            index: no_index;
            columns: atomic_number, ion_number, source_level_number, count_down, count_up, count_total.

        Refer to the docs: http://tardis.readthedocs.io/en/latest/physics/plasma/macroatom.html

    collision_data: (pandas.DataFrame, np.array)
        A DataFrame containing the *electron collisions data* with:
            index: atomic_number, ion_number, level_number_lower, level_number_upper;
            columns: e_col_id, delta_e, g_ratio, c_ul;

    collision_data_temperatures: np.array
        An array with the collision temperatures.

    zeta_data: ?
    synpp_refs: ?
    ion_cx_tx_data: ?
    ion_cx_sp_data: ?

    Attributes
    -------------
    prepared: bool

    atom_data: pandas.DataFrame
    ionization_data: pandas.DataFrame
    macro_atom_data_all: pandas.DataFrame
    macro_atom_references_all: pandas.DataFrame
    collision_data: pandas.DataFrame
    collision_data_temperatures: numpy.array
    zeta_data: pandas.DataFrame
    synpp_refs: pandas.DataFrame
    ion_cx_tx_data: pandas.DataFrame
    ion_cx_sp_data: pandas.DataFrame
    symbol2atomic_number: OrderedDict
    atomic_number2symbol OrderedDict

    Methods
    --------
    from_hdf
    prepare_atom_data

    Notes
    ------
    1. The units of some columns are given in the square brackets. They are **NOT** the parts of columns' names!

    """

    hdf_names = ["atom_data", "ionization_data", "levels", "lines",
                 "macro_atom_data", "macro_atom_references", "zeta_data", "collision_data",
                 "collision_data_temperatures", "synpp_refs", "ion_cx_th_data", "ion_cx_sp_data"]

    @classmethod
    def from_hdf(cls, fname=None):
        """
        Function to read all the atom data from the special Carsus HDFStore file.

        Parameters
        ----------

        fname: str, optional
            The path to the HDFStore file. If set to `None` the default file with limited atomic_data
            shipped with TARDIS will be used. For more complex atomic data please contact the authors.
            (default: None)
        """

        if fname is None:
            fname = default_atom_h5_path

        if not os.path.exists(fname):
            raise ValueError("Supplied Atomic Model Database %s does not exists" % fname)

        dataframes = dict()
        nonavailable = list()

        with pd.HDFStore(fname) as store:
            for name in cls.hdf_names:
                try:
                    dataframes[name] = store[name]
                except KeyError:
                    nonavailable.append(name)

            atom_data = cls(**dataframes)

            try:
                atom_data.uuid1 = store.root._v_attrs['uuid1']
            except KeyError:
                atom_data.uuid1 = None

            try:
                atom_data.md5 = store.root._v_attrs['md5']
            except KeyError:
                atom_data.md5 = None

            try:
                atom_data.version = store.root._v_attrs['database_version']
            except KeyError:
                atom_data.version = None

            # ToDo: strore data sources as attributes in carsus

            logger.info(
                "Read Atom Data with UUID={0} and MD5={1}. "
                "Not found: {2}".format(atom_data.uuid1, atom_data.md5, ", ".join(nonavailable))
            )


        return atom_data

    def __init__(self, atom_data, ionization_data, levels=None, lines=None,
                 macro_atom_data=None, macro_atom_references=None, zeta_data=None,
{'fraction_non_alphanumeric': 0.08734144888056525, 'fraction_numerical': 0.004256405890865753, 'mean_word_length': 2.4512338425381905, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '191925', 'n_tokens_mistral': 3580, 'n_tokens_neox': 3399, 'n_words': 889}