Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/AWehrhahn/SME
Browse files Browse the repository at this point in the history
  • Loading branch information
AWehrhahn committed Dec 3, 2020
2 parents 75a3b0e + 18bac5e commit 84baa49
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 5 deletions.
2 changes: 2 additions & 0 deletions src/pysme/atmosphere/atmosphere.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ def __init__(self, **kwargs):
monh = kwargs.pop("monh", kwargs.pop("feh", 0))
abund = kwargs.pop("abund", "empty")
abund_format = kwargs.pop("abund_format", "sme")
if "geom" in kwargs.keys() and kwargs["geom"] == "":
kwargs["geom"] = None
super().__init__(**kwargs)
self.abund = Abund(monh=monh, pattern=abund, type=abund_format)

Expand Down
107 changes: 107 additions & 0 deletions src/pysme/linelist/ges.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
"""
Module for handling linelist data from the VALD3 database (http://vald.astro.uu.se/).
"""
import logging
import re
from io import StringIO
from os.path import dirname, join
import sys

import numpy as np
import pandas as pd
from astropy import units as u
import pybtex.database

from astropy.io import fits


from ..abund import Abund
from .linelist import LineListError, LineList

logger = logging.getLogger(__name__)


class GesError(LineListError):
""" Vald Data File Error """


class GesFile(LineList):
"""Atomic data for a list of spectral lines.
"""

def __init__(self, filename, medium=None):
self.filename = filename
linelist = self.loads(filename)

super().__init__(linelist, lineformat=self.lineformat, medium=self.medium)
# Convert to desired medium
if medium is not None:
self.medium = medium

@staticmethod
def load(filename):
"""
Read line data file from the VALD extract stellar service
Parameters
----------
filename : str
Name of the VALD linelist file to read
Returns
-------
vald : ValdFile
Parsed vald file
"""
return GesFile(filename)

def loads(self, filename):
logger.info("Loading GES file %s", filename)

hdu = fits.open(filename)
data = hdu[1].data

linedata = {
"species": data["name"][:, 0] + " " + data["ion"].astype(str),
"atom_number": np.zeros(len(data)),
"ionization": data["ion"],
"wlcent": data["lambda"],
"excit": data["e_low"],
"gflog": data["log_gf"],
"gflog_err": data["log_gf_err"],
"gamrad": data["rad_damp"],
"gamqst": data["stark_damp"],
"gamvw": data["vdw_damp"],
"lande": data["lande_mean"],
"depth": data["depth"],
"reference": data["lambda_ref"],
"lande_lower": data["lande_low"],
"lande_upper": data["lande_up"],
"j_lo": data["j_low"],
"e_upp": data["e_up"],
"j_up": data["j_up"],
"term_lower": data["label_low"],
"term_upper": data["label_up"],
}

sort = np.argsort(linedata["wlcent"])

# We need to make sure all data is in the system defined byteorder
# Otherwise pandas will not work properly
for key, value in linedata.items():
if (value.dtype.byteorder == ">" and sys.byteorder == "little") or (
value.dtype.byteorder == "<" and sys.byteorder == "big"
):
value = value.byteswap().newbyteorder()
linedata[key] = value[sort]

linelist = pd.DataFrame.from_dict(linedata)
self.lineformat = "long"
self.unit = "Angstrom"
self._medium = "air"

# self.citation_info += self.parse_references(refdata, fmt)

return linelist
36 changes: 31 additions & 5 deletions src/pysme/linelist/linelist.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ def parse_line_error(error_flags, values=None):
}
error = np.ones(len(error_flags), dtype=float)
for i, (flag, _) in enumerate(zip(error_flags, values)):
if flag[0] in [" ", "_", "P"]:
if len(flag) == 0:
error[i] = 0.5
elif flag[0] in [" ", "_", "P"]:
# undefined or predicted
error[i] = 0.5
elif flag[0] == "E":
Expand All @@ -88,22 +90,46 @@ def parse_line_error(error_flags, values=None):
error[i] = 10 ** float(flag[1:])
elif flag[0] == "C":
# Cancellation Factor, i.e. relative error
error[i] = abs(float(flag[1:]))
try:
error[i] = abs(float(flag[1:]))
except ValueError:
error[i] = 0.5
elif flag[0] == "N":
# NIST quality class
flag = flag[1:5].strip()
error[i] = nist[flag]
try:
error[i] = nist[flag]
except KeyError:
error[i] = 0.5
return error

@staticmethod
def from_IDL_SME(**kwargs):
def guess_format(kwargs):
short_line_format = kwargs.pop(
"short_line_format", kwargs.pop("short_format", None)
)
if short_line_format is not None:
return short_line_format

keys = kwargs.keys()
if (
"line_extra" in keys
and "line_lulande" in keys
and "line_term_low" in keys
and "line_term_upp" in keys
):
return 2
return 1

@classmethod
def from_IDL_SME(cls, **kwargs):
""" extract LineList from IDL SME structure keywords """
species = kwargs.pop("species").astype("U")
atomic = np.asarray(kwargs.pop("atomic"), dtype="<f8")
lande = np.asarray(kwargs.pop("lande"), dtype="<f8")
depth = np.asarray(kwargs.pop("depth"), dtype="<f8")
lineref = kwargs.pop("lineref").astype("U")
short_line_format = kwargs.pop("short_line_format")
short_line_format = cls.guess_format(kwargs)
if short_line_format == 2:
line_extra = np.asarray(kwargs.pop("line_extra"), dtype="<f8")
line_lulande = np.asarray(kwargs.pop("line_lulande"), dtype="<f8")
Expand Down
2 changes: 2 additions & 0 deletions src/pysme/sme.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ def __init__(self, **kwargs):
# Parse free parameters into one list
pname = kwargs.get("pname", [])
glob_free = kwargs.get("glob_free", [])
if isinstance(glob_free, str):
glob_free = [glob_free]
ab_free = kwargs.get("ab_free", [])
if len(ab_free) != 0:
ab_free = [f"abund {el}" for i, el in zip(ab_free, abund_elem) if i == 1]
Expand Down

0 comments on commit 84baa49

Please sign in to comment.