Ejemplo n.º 1
0
    def __init__(self,
                 session,
                 fname=None,
                 ions=None,
                 unique_level_identifier=None,
                 ds_short_name="ku_latest"):
        self.session = session

        if fname is None:
            self.fname = GFALL_URL
        else:
            self.fname = fname

        self.gfall_reader = GFALLReader(ions, self.fname,
                                        unique_level_identifier)

        if ions is not None:
            try:
                ions = parse_selected_species(ions)
            except ParseException:
                raise ValueError(
                    'Input is not a valid species string {}'.format(ions))
            ions = pd.DataFrame.from_records(
                ions, columns=["atomic_number", "ion_charge"])
            self.ions = ions.set_index(['atomic_number', 'ion_charge'])
        else:
            self.ions = None

        self.data_source = DataSource.as_unique(self.session,
                                                short_name=ds_short_name)
        if self.data_source.data_source_id is None:  # To get the id if a new data source was created
            self.session.flush()
Ejemplo n.º 2
0
    def __init__(self, session, ions=None, ds_short_name=None):
        if ds_short_name is None:
            ds_short_name = '{}_v{}'.format(self.ds_prefix, masterlist_version)

        self.session = session
        self.ion_readers = list()
        self.ions = list()

        if ions is not None:
            try:
                ions = parse_selected_species(ions)
            except ParseException:
                raise ValueError(
                    'Input is not a valid species string {}'.format(ions))
            self.ions = [convert_species_tuple2chianti_str(_) for _ in ions]
        else:
            self.ions = masterlist_ions

        for ion in self.ions:
            if ion in self.masterlist_ions:
                self.ion_readers.append(ChiantiIonReader(ion))
            else:
                logger.info("Ion {0} is not available.".format(ion))

        self.data_source = DataSource.as_unique(self.session,
                                                short_name=ds_short_name)
        # To get the id if a new data source was created
        if self.data_source.data_source_id is None:
            self.session.flush()
Ejemplo n.º 3
0
    def __init__(self, session, ions=None, ds_short_name="chianti_v8.0.2"):
        self.session = session
        # ToDo write a parser for Spectral Notation
        self.ion_readers = list()
        self.ions = list()

        if ions is not None:
            try:
                ions = parse_selected_species(ions)
            except ParseException:
                raise ValueError(
                    'Input is not a valid species string {}'.format(ions))
            self.ions = [convert_species_tuple2chianti_str(_) for _ in ions]
        else:
            self.ions = masterlist_ions

        for ion in self.ions:
            if ion in self.masterlist_ions:
                self.ion_readers.append(ChiantiIonReader(ion))
            else:
                print("Ion {0} is not available".format(ion))

        self.data_source = DataSource.as_unique(self.session,
                                                short_name=ds_short_name)
        if self.data_source.data_source_id is None:  # To get the id if a new data source was created
            self.session.flush()
Ejemplo n.º 4
0
    def __init__(self, ions, collisions=False, priority=10):
        """
        Parameters
        ----------
        ions : string
            Selected Chianti ions.

        collisions: bool, optional
            Grab collisional data, by default False.

        priority: int
            Priority of the current data source.        
        """
        self.ions = parse_selected_species(ions)
        self.priority = priority
        self._get_levels_lines(get_collisions=collisions)
Ejemplo n.º 5
0
    def __init__(self, session, fname, ions=None, ds_short_name="ku_latest"):
        self.session = session
        self.gfall_reader = GFALLReader(fname)
        if ions is not None:
            try:
                ions = parse_selected_species(ions)
            except ParseException:
                raise ValueError('Input is not a valid species string {}'.format(ions))
            ions = pd.DataFrame.from_records(ions, columns=["atomic_number", "ion_charge"])
            self.ions = ions.set_index(['atomic_number', 'ion_charge'])
        else:
            self.ions = None

        self.data_source = DataSource.as_unique(self.session, short_name=ds_short_name)
        if self.data_source.data_source_id is None:  # To get the id if a new data source was created
            self.session.flush()
Ejemplo n.º 6
0
    def __init__(self,
                 ions=None,
                 fname=None,
                 unique_level_identifier=None,
                 priority=10):
        """
        Parameters
        ----------
        fname: str
            Path to the gfall file (http or local file).

        ions: str, optional
            Ions to extract, by default None.

        unique_level_identifier: list
            List of attributes to identify unique levels from. Will always use
            atomic_number and ion charge in addition.

        priority: int, optional
            Priority of the current data source.
        """

        if fname is None:
            self.fname = GFALL_URL
        else:
            self.fname = fname

        self.priority = priority

        if ions is not None:
            self.ions = parse_selected_species(ions)

        else:
            self.ions = None

        self._gfall_raw = None
        self._gfall = None
        self._levels = None
        self._lines = None
        if unique_level_identifier is None:
            logger.warn(
                'A specific combination to identify unique levels from '
                'GFALL data has not been given. Defaulting to '
                '["energy", "j"].')
            self.unique_level_identifier = self.default_unique_level_identifier
        else:
            self.unique_level_identifier = unique_level_identifier
Ejemplo n.º 7
0
    def __init__(self, gfall_reader, ionization_energies, ions,
                 lines_loggf_threshold=-3,
                 levels_metastable_loggf_threshold=-3):

        self.levels_lines_param = {
            "levels_metastable_loggf_threshold":
            levels_metastable_loggf_threshold,
            "lines_loggf_threshold": lines_loggf_threshold
        }

        self.ions = parse_selected_species(ions)
        self.gfall_reader = gfall_reader

        self.ionization_energies = ionization_energies.base
        self.ground_levels = ionization_energies.get_ground_levels()

        self.levels_all = self._get_all_levels_data().reset_index()
        self.lines_all = self._get_all_lines_data(self.levels_all)

        self._create_levels_lines(**self.levels_lines_param)
        self._create_macro_atom()
        self._create_macro_atom_references()
Ejemplo n.º 8
0
    def __init__(self, ions=None, 
                 fname='http://kurucz.harvard.edu/linelists/gfall/gfall.dat',
                 priority=10, unique_level_identifier=None):
        """

        Parameters
        ----------
        fname: str
            path to the gfall file (http or local file)

        ions: str, optional
            ions to extract, by default None

        unique_level_identifier: list
            list of attributes to identify unique levels from. Will always use
            atomic_number and ion charge in addition.
        """
        self.fname = fname
        self.priority = priority

        if ions is not None:
            self.ions = parse_selected_species(ions)

        else:
            self.ions = None

        self._gfall_raw = None
        self._gfall = None
        self._levels = None
        self._lines = None
        if unique_level_identifier is None:
            logger.warn('A specific combination to identify unique levels from '
                        'GFALL data has not been given. Defaulting to '
                        '["energy", "j"].')
            self.unique_level_identifier = self.default_unique_level_identifier
        else:
            self.unique_level_identifier = unique_level_identifier
Ejemplo n.º 9
0
    def __init__(
        self,
        session,
        selected_atoms,
        chianti_ions=None,
        kurucz_short_name="ku_latest",
        chianti_short_name="chianti_v8.0.2",
        nist_short_name="nist-asd",
        atom_masses_max_atomic_number=30,
        lines_loggf_threshold=-3,
        levels_metastable_loggf_threshold=-3,
        collisions_temperatures=None,
    ):

        self.session = session

        # Set the parameters for the dataframes
        self.atom_masses_param = {
            "max_atomic_number": atom_masses_max_atomic_number
        }

        self.levels_lines_param = {
            "levels_metastable_loggf_threshold":
            levels_metastable_loggf_threshold,
            "lines_loggf_threshold": lines_loggf_threshold
        }

        if collisions_temperatures is None:
            collisions_temperatures = np.arange(2000, 50000, 2000)
        else:
            collisions_temperatures = np.array(collisions_temperatures,
                                               dtype=np.int64)

        self.collisions_param = {"temperatures": collisions_temperatures}

        try:
            self.selected_atomic_numbers = list(
                map(int, parse_selected_atoms(selected_atoms)))
        except ParseException:
            raise ValueError(
                'Input is not a valid atoms string {}'.format(selected_atoms))

        if chianti_ions is not None:
            # Get a list of tuples (atomic_number, ion_charge) for the chianti ions

            try:
                self.chianti_ions = parse_selected_species(chianti_ions)
                self.chianti_ions = [
                    tuple(map(int, t)) for t in self.chianti_ions
                ]

            except ParseException:
                raise ValueError(
                    'Input is not a valid species string {}'.format(
                        chianti_ions))

            try:
                chianti_atomic_numbers = {
                    atomic_number
                    for atomic_number, ion_charge in self.chianti_ions
                }
                assert chianti_atomic_numbers.issubset(
                    set(self.selected_atomic_numbers))
            except AssertionError:
                raise ValueError(
                    "Chianti ions *must* be species of selected atoms!")
        else:
            self.chianti_ions = list()

        self._chianti_ions_table = None

        # Query the data sources
        self.ku_ds = None
        self.ch_ds = None
        self.nist_ds = None

        try:
            self.ku_ds = session.query(DataSource).filter(
                DataSource.short_name == kurucz_short_name).one()
        except NoResultFound:
            raise NoResultFound("Kurucz data source is not found!")

        try:
            self.nist_ds = session.query(DataSource).filter(
                DataSource.short_name == nist_short_name).one()
        except NoResultFound:
            raise NoResultFound("NIST ASD data source is not found!")

        if self.chianti_ions:
            try:
                self.ch_ds = session.query(DataSource).filter(
                    DataSource.short_name == chianti_short_name).one()
            except NoResultFound:
                raise NoResultFound("Chianti data source is not found!")

        self._atom_masses = None
        self._ionization_energies = None
        self._levels = None
        self._lines = None
        self._collisions = None
        self._macro_atom = None
        self._macro_atom_references = None
        self._zeta_data = None
Ejemplo n.º 10
0
    def _get_levels_lines(self, data):
        """ Generates `levels` and `lines` DataFrames.

        Parameters
        ----------
        data : dict
            Dictionary containing one dictionary per specie with 
            keys `levels` and `lines`.
        """
        lvl_list = []
        lns_list = []
        for ion, parser in data.items():

            atomic_number = parse_selected_species(ion)[0][0]
            ion_charge = parse_selected_species(ion)[0][1]

            lvl = parser['levels'].base
            # some ID's have negative values (theoretical?)
            lvl.loc[lvl['ID'] < 0, 'method'] = 'theor'
            lvl.loc[lvl['ID'] > 0, 'method'] = 'meas'
            lvl['ID'] = np.abs(lvl['ID'])
            lvl_id = lvl.set_index('ID')
            lvl['atomic_number'] = atomic_number
            lvl['ion_charge'] = ion_charge  # i.e. Si I = (14,0) then `ion_charge` = 0
            lvl_list.append(lvl)

            lns = parser['lines'].base
            lns = lns.set_index(['i', 'j'])
            lns['energy_lower'] = lvl_id['E(cm^-1)'].reindex(lns.index,
                                                             level=0).values
            lns['energy_upper'] = lvl_id['E(cm^-1)'].reindex(lns.index,
                                                             level=1).values
            lns['g_lower'] = lvl_id['g'].reindex(lns.index, level=0).values
            lns['g_upper'] = lvl_id['g'].reindex(lns.index, level=1).values
            lns['j_lower'] = (lns['g_lower'] - 1) / 2
            lns['j_upper'] = (lns['g_upper'] - 1) / 2
            lns['atomic_number'] = atomic_number
            lns['ion_charge'] = ion_charge
            lns = lns.reset_index()
            lns_list.append(lns)

        levels = pd.concat(lvl_list)
        levels['priority'] = self.priority
        levels = levels.reset_index(drop=False)
        levels = levels.rename(columns={
            'Configuration': 'label',
            'E(cm^-1)': 'energy',
            'index': 'level_index'
        })
        levels['j'] = (levels['g'] - 1) / 2
        levels = levels.set_index(
            ['atomic_number', 'ion_charge', 'level_index'])
        levels = levels[['energy', 'j', 'label', 'method', 'priority']]

        lines = pd.concat(lns_list)
        lines = lines.rename(columns={'Lam(A)': 'wavelength'})
        lines['wavelength'] = u.Quantity(lines['wavelength'],
                                         u.AA).to('nm').value
        lines['level_index_lower'] = lines['i'] - 1
        lines['level_index_upper'] = lines['j'] - 1
        lines['gf'] = lines['f'] * lines['g_lower']
        lines = lines.set_index([
            'atomic_number', 'ion_charge', 'level_index_lower',
            'level_index_upper'
        ])
        lines = lines[[
            'energy_lower', 'energy_upper', 'gf', 'j_lower', 'j_upper',
            'wavelength'
        ]]

        self.levels = levels
        self.lines = lines

        return
Ejemplo n.º 11
0
    def __init__(self, session, selected_atoms, chianti_ions=None,
                 kurucz_short_name="ku_latest", chianti_short_name="chianti_v8.0.2", nist_short_name="nist-asd",
                 atom_masses_max_atomic_number=30, lines_loggf_threshold=-3, levels_metastable_loggf_threshold=-3,
                 collisions_temperatures=None,
                 ):

        self.session = session

        # Set the parameters for the dataframes
        self.atom_masses_param = {
            "max_atomic_number": atom_masses_max_atomic_number
        }

        self.levels_lines_param = {
            "levels_metastable_loggf_threshold": levels_metastable_loggf_threshold,
            "lines_loggf_threshold": lines_loggf_threshold
        }

        if collisions_temperatures is None:
            collisions_temperatures = np.arange(2000, 50000, 2000)
        else:
            collisions_temperatures = np.array(collisions_temperatures, dtype=np.int64)

        self.collisions_param = {
            "temperatures": collisions_temperatures
        }

        try:
            self.selected_atomic_numbers = parse_selected_atoms(selected_atoms)
        except ParseException:
            raise ValueError('Input is not a valid atoms string {}'.format(selected_atoms))

        if chianti_ions is not None:
            # Get a list of tuples (atomic_number, ion_charge) for the chianti ions

            try:
                self.chianti_ions = parse_selected_species(chianti_ions)
            except ParseException:
                raise ValueError('Input is not a valid species string {}'.format(chianti_ions))

            try:
                chianti_atomic_numbers = {atomic_number for atomic_number, ion_charge in self.chianti_ions}
                assert chianti_atomic_numbers.issubset(set(self.selected_atomic_numbers))
            except AssertionError:
                raise ValueError("Chianti ions *must* be species of selected atoms!")
        else:
            self.chianti_ions = list()

        self._chianti_ions_table = None

        # Query the data sources
        self.ku_ds = None
        self.ch_ds = None
        self.nist_ds = None

        try:
            self.ku_ds = session.query(DataSource).filter(DataSource.short_name == kurucz_short_name).one()
        except NoResultFound:
            raise NoResultFound("Kurucz data source is not found!")

        try:
            self.nist_ds = session.query(DataSource).filter(DataSource.short_name == nist_short_name).one()
        except NoResultFound:
            raise NoResultFound("NIST ASD data source is not found!")

        if self.chianti_ions:
            try:
                self.ch_ds = session.query(DataSource).filter(DataSource.short_name == chianti_short_name).one()
            except NoResultFound:
                raise NoResultFound("Chianti data source is not found!")

        self._atom_masses = None
        self._ionization_energies = None
        self._levels = None
        self._lines = None
        self._collisions = None
        self._macro_atom = None
        self._macro_atom_references = None
        self._zeta_data = None