Beispiel #1
0
    def ingest_lines(self):

        logger.info("Ingesting lines from `{}`.".format(
            self.data_source.short_name))

        for rdr in self.ion_readers:

            atomic_number = rdr.ion.Z
            ion_charge = rdr.ion.Ion - 1

            ion = Ion.as_unique(self.session,
                                atomic_number=atomic_number,
                                ion_charge=ion_charge)

            try:
                bound_lines = rdr.bound_lines
            except ChiantiIonReaderError:
                logger.info("Lines not found for ion {} {}.".format(
                    convert_atomic_number2symbol(atomic_number), ion_charge))
                continue

            logger.info("Ingesting lines for {} {}.".format(
                convert_atomic_number2symbol(atomic_number), ion_charge))

            lvl_index2id = self.get_lvl_index2id(ion)

            for index, row in bound_lines.iterrows():

                # index: (lower_level_index, upper_level_index)
                lower_level_index, upper_level_index = index

                try:
                    lower_level_id = int(lvl_index2id.loc[lower_level_index])
                    upper_level_id = int(lvl_index2id.loc[upper_level_index])
                except KeyError:
                    raise IngesterError(
                        "Levels from this source have not been found."
                        "You must ingest levels before transitions")

                # Create a new line
                line = Line(
                    lower_level_id=lower_level_id,
                    upper_level_id=upper_level_id,
                    data_source=self.data_source,
                    wavelengths=[
                        LineWavelength(quantity=row["wavelength"] * u.AA,
                                       data_source=self.data_source,
                                       medium=MEDIUM_VACUUM,
                                       method=row["method"])
                    ],
                    a_values=[
                        LineAValue(quantity=row["a_value"] * u.Unit("s**-1"),
                                   data_source=self.data_source)
                    ],
                    gf_values=[
                        LineGFValue(quantity=row["gf_value"],
                                    data_source=self.data_source)
                    ])

                self.session.add(line)
Beispiel #2
0
def convert_species_tuple2chianti_str(species):
    """
    Convert a species tuple to the ion name format used in `chiantipy`.

    Parameters
    -----------
    species: tuple (atomic_number, ion_number)

    Returns
    --------
    str
        ion name in the chiantipy format

    Examples
    ---------
    >>> convert_species_tuple2chianti_str((1,0))
    'h_1'

    >>> convert_species_tuple2chianti_str((14,1))
    'si_2'

    """
    atomic_number, ion_number = species
    chianti_ion_name = convert_atomic_number2symbol(
        atomic_number).lower() + '_' + str(ion_number + 1)
    return chianti_ion_name
Beispiel #3
0
    def create_ionization_energies(self):
        """
        Create a DataFrame containing *ionization energies*.

        Returns
        -------
        ionization_energies : pandas.DataFrame
            DataFrame with:
                index: none;
                columns: atomic_number, ion_number, ionization_energy[eV]
        """
        ionization_energies_q = self.session.query(Ion).\
            filter(Ion.atomic_number.in_(self.selected_atomic_numbers)).\
            order_by(Ion.atomic_number, Ion.ion_charge)

        ionization_energies = list()
        for ion in ionization_energies_q.options(joinedload(Ion.ionization_energies)):
            try:
                ionization_energy = ion.ionization_energies[0].quantity
            except IndexError:
                print "No ionization energy is available for ion {0} {1}".format(
                    convert_atomic_number2symbol(ion.atomic_number), ion.ion_charge
                )
                continue
            ionization_energies.append((ion.atomic_number, ion.ion_charge, ionization_energy.value))

        ionization_dtype = [("atomic_number", np.int), ("ion_number", np.int), ("ionization_energy", np.float)]
        ionization_energies = np.array(ionization_energies, dtype=ionization_dtype)

        ionization_energies = pd.DataFrame.from_records(ionization_energies)

        return ionization_energies
Beispiel #4
0
def convert_species_tuple2chianti_str(species):
    """
    Convert a species tuple to the ion name format used in `chiantipy`.

    Parameters
    -----------
    species: tuple (atomic_number, ion_number)

    Returns
    --------
    str
        ion name in the chiantipy format

    Examples
    ---------
    >>> convert_species_tuple2chianti_str((1,0))
    'h_1'

    >>> convert_species_tuple2chianti_str((14,1))
    'si_2'

    """
    atomic_number, ion_number = species
    chianti_ion_name = convert_atomic_number2symbol(atomic_number).lower() + '_' + str(ion_number + 1)
    return chianti_ion_name
Beispiel #5
0
    def ingest_levels(self, levels=None):

        if levels is None:
            levels = self.gfall_reader.levels

        # Select ions
        if self.ions is not None:
            levels = levels.reset_index().\
                                  join(self.ions, how="inner",
                                       on=["atomic_number", "ion_charge"]).\
                                  set_index(["atomic_number", "ion_charge", "level_index"])

        print("Ingesting levels from {}".format(self.data_source.short_name))

        for ion_index, ion_levels in levels.groupby(level=["atomic_number", "ion_charge"]):

            atomic_number, ion_charge = ion_index
            ion = Ion.as_unique(self.session, atomic_number=atomic_number, ion_charge=ion_charge)

            print("Ingesting levels for {} {}".format(convert_atomic_number2symbol(atomic_number), ion_charge))

            for index, row in ion_levels.iterrows():

                level_index = index[2]  # index: (atomic_number, ion_charge, level_index)

                ion.levels.append(
                    Level(level_index=level_index,
                          data_source=self.data_source,
                          J=row["j"],
                          energies=[
                              LevelEnergy(quantity=row["energy"]*u.Unit("cm-1"),
                                          method=row["method"],
                                          data_source=self.data_source)
                          ])
                )
Beispiel #6
0
    def ingest_lines(self, lines=None):

        if lines is None:
            lines = self.gfall_reader.lines

        # Select ions
        if self.ions is not None:
            lines = lines.reset_index(). \
                join(self.ions, how="inner",
                     on=["atomic_number", "ion_charge"]). \
                set_index(["atomic_number", "ion_charge", "level_index_lower", "level_index_upper"])

        print("Ingesting lines from {}".format(self.data_source.short_name))

        for ion_index, ion_lines in lines.groupby(
                level=["atomic_number", "ion_charge"]):

            atomic_number, ion_charge = ion_index
            ion = Ion.as_unique(self.session,
                                atomic_number=atomic_number,
                                ion_charge=ion_charge)

            print("Ingesting lines for {} {}".format(
                convert_atomic_number2symbol(atomic_number), ion_charge))

            lvl_index2id = self.get_lvl_index2id(ion)

            for index, row in ion_lines.iterrows():

                # index: (atomic_number, ion_charge, lower_level_index, upper_level_index)
                lower_level_index, upper_level_index = index[2:]

                try:
                    lower_level_id = int(lvl_index2id.loc[lower_level_index])
                    upper_level_id = int(lvl_index2id.loc[upper_level_index])
                except KeyError:
                    raise IngesterError(
                        "Levels from this source have not been found."
                        "You must ingest levels before transitions")

                medium = MEDIUM_VACUUM if row[
                    "wavelength"] <= GFALL_AIR_THRESHOLD else MEDIUM_AIR

                # Create a new line
                line = Line(lower_level_id=lower_level_id,
                            upper_level_id=upper_level_id,
                            data_source=self.data_source,
                            wavelengths=[
                                LineWavelength(quantity=row["wavelength"] *
                                               u.nm,
                                               medium=medium,
                                               data_source=self.data_source)
                            ],
                            gf_values=[
                                LineGFValue(quantity=row["gf"],
                                            data_source=self.data_source)
                            ])

                self.session.add(line)
Beispiel #7
0
    def ingest_levels(self):

        logger.info("Ingesting levels from `{}`.".format(
            self.data_source.short_name))

        for rdr in self.ion_readers:

            atomic_number = rdr.ion.Z
            ion_charge = rdr.ion.Ion - 1

            ion = Ion.as_unique(self.session,
                                atomic_number=atomic_number,
                                ion_charge=ion_charge)

            try:
                bound_levels = rdr.bound_levels
            except ChiantiIonReaderError:
                logger.info("Levels not found for ion {} {}.".format(
                    convert_atomic_number2symbol(atomic_number), ion_charge))
                continue

            logger.info("Ingesting levels for {} {}.".format(
                convert_atomic_number2symbol(atomic_number), ion_charge))

            # ToDo: Determine parity from configuration

            for index, row in bound_levels.iterrows():

                level = Level(ion=ion,
                              data_source=self.data_source,
                              level_index=index,
                              configuration=row["configuration"],
                              term=row["term"],
                              L=row["L"],
                              J=row["J"],
                              spin_multiplicity=row["spin_multiplicity"])

                level.energies = []
                for column, method in [('energy', 'meas'),
                                       ('energy_theoretical', 'theor')]:
                    if row[column] != -1:  # check if the value exists
                        level.energies.append(
                            LevelEnergy(quantity=row[column] * u.Unit("cm-1"),
                                        data_source=self.data_source,
                                        method=method), )
                self.session.add(level)
Beispiel #8
0
    def ingest_lines(self, lines=None):

        if lines is None:
            lines = self.gfall_reader.lines

        # Select ions
        if self.ions is not None:
            lines = lines.reset_index(). \
                join(self.ions, how="inner",
                     on=["atomic_number", "ion_charge"]). \
                set_index(["atomic_number", "ion_charge", "level_index_lower", "level_index_upper"])

        print("Ingesting lines from {}".format(self.data_source.short_name))

        for ion_index, ion_lines in lines.groupby(level=["atomic_number", "ion_charge"]):

            atomic_number, ion_charge = ion_index
            ion = Ion.as_unique(self.session, atomic_number=atomic_number, ion_charge=ion_charge)

            print("Ingesting lines for {} {}".format(convert_atomic_number2symbol(atomic_number), ion_charge))

            lvl_index2id = self.get_lvl_index2id(ion)

            for index, row in ion_lines.iterrows():

                # index: (atomic_number, ion_charge, lower_level_index, upper_level_index)
                lower_level_index, upper_level_index = index[2:]

                try:
                    lower_level_id = int(lvl_index2id.loc[lower_level_index])
                    upper_level_id = int(lvl_index2id.loc[upper_level_index])
                except KeyError:
                    raise IngesterError("Levels from this source have not been found."
                                        "You must ingest levels before transitions")

                medium = MEDIUM_VACUUM if row["wavelength"] <= GFALL_AIR_THRESHOLD else MEDIUM_AIR

                # Create a new line
                line = Line(
                    lower_level_id=lower_level_id,
                    upper_level_id=upper_level_id,
                    data_source=self.data_source,
                    wavelengths=[
                        LineWavelength(quantity=row["wavelength"] * u.nm,
                                       medium=medium,
                                       data_source=self.data_source)
                    ],
                    gf_values=[
                        LineGFValue(quantity=row["gf"],
                                    data_source=self.data_source)
                    ]
                )

                self.session.add(line)
Beispiel #9
0
    def ingest_levels(self, levels=None):

        if levels is None:
            levels = self.gfall_reader.levels

        # Select ions
        if self.ions is not None:
            levels = levels.reset_index().\
                join(self.ions, how="inner",
                     on=["atomic_number", "ion_charge"]).\
                set_index(["atomic_number", "ion_charge", "level_index"])

        logger.info("Ingesting levels from `{}`.".format(
            self.data_source.short_name))

        for ion_index, ion_levels in levels.groupby(
                level=["atomic_number", "ion_charge"]):

            atomic_number, ion_charge = ion_index
            ion = Ion.as_unique(self.session,
                                atomic_number=atomic_number,
                                ion_charge=ion_charge)

            logger.info("Ingesting levels for {} {}.".format(
                convert_atomic_number2symbol(atomic_number), ion_charge))

            for index, row in ion_levels.iterrows():

                # index: (atomic_number, ion_charge, level_index)
                level_index = index[2]

                ion.levels.append(
                    Level(level_index=level_index,
                          data_source=self.data_source,
                          J=row["j"],
                          energies=[
                              LevelEnergy(quantity=row["energy"] *
                                          u.Unit("cm-1"),
                                          method=row["method"],
                                          data_source=self.data_source)
                          ]))
Beispiel #10
0
    def ingest_collisions(self):

        logger.info("Ingesting collisions from `{}`.".format(
            self.data_source.short_name))

        for rdr in self.ion_readers:

            atomic_number = rdr.ion.Z
            ion_charge = rdr.ion.Ion - 1

            ion = Ion.as_unique(self.session,
                                atomic_number=atomic_number,
                                ion_charge=ion_charge)

            try:
                bound_collisions = rdr.bound_collisions
            except ChiantiIonReaderError:
                logger.info("Collisions not found for ion {} {}.".format(
                    convert_atomic_number2symbol(atomic_number), ion_charge))
                continue

            logger.info("Ingesting collisions for {} {}.".format(
                convert_atomic_number2symbol(atomic_number), ion_charge))

            lvl_index2id = self.get_lvl_index2id(ion)

            for index, row in bound_collisions.iterrows():

                # index: (lower_level_index, upper_level_index)
                lower_level_index, upper_level_index = index

                try:
                    lower_level_id = int(lvl_index2id.loc[lower_level_index])
                    upper_level_id = int(lvl_index2id.loc[upper_level_index])
                except KeyError:
                    raise IngesterError(
                        "Levels from this source have not been found."
                        "You must ingest levels before transitions")

                # Create a new electron collision
                e_col = ECollision(
                    lower_level_id=lower_level_id,
                    upper_level_id=upper_level_id,
                    data_source=self.data_source,
                    bt92_ttype=row["ttype"],
                    bt92_cups=row["cups"],
                    energies=[
                        ECollisionEnergy(quantity=row["energy"] * u.rydberg,
                                         data_source=self.data_source)
                    ],
                    gf_values=[
                        ECollisionGFValue(quantity=row["gf_value"],
                                          data_source=self.data_source)
                    ])

                e_col.temp_strengths = [
                    ECollisionTempStrength(temp=temp, strength=strength)
                    for temp, strength in zip(row["temperatures"],
                                              row["collision_strengths"])
                ]

                self.session.add(e_col)