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)
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
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
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
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) ]) )
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)
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)
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)
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) ]))
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)