#!/usr/bin/env python3
from typing import Optional
from amespahdbpythonsuite import laboratory
from amespahdbpythonsuite import geometry
from amespahdbpythonsuite import transitions
import copy
import re
import astropy.units as u # type: ignore
from amespahdbpythonsuite.amespahdb import AmesPAHdb
message = AmesPAHdb.message
[docs]
class Species:
"""
AmesPAHdbPythonSuite species class.
Contains methods to work with PAH species.
"""
def __init__(self, d: Optional[dict] = None, **keywords) -> None:
self.set(d, **keywords)
[docs]
def set(self, d: Optional[dict] = None, **keywords) -> None:
"""
Populate properties.
"""
self.database = keywords.get("database", "")
self.version = keywords.get("version", "")
self.data = keywords.get("data", dict())
self.pahdb = keywords.get("pahdb", None)
self.uids = keywords.get("uids", list())
if isinstance(d, dict):
if d.get("type", "") == self.__class__.__name__:
if "database" not in keywords:
self.database = d["database"]
if "version" not in keywords:
self.version = d["version"]
if "data" not in keywords:
self.data = d["data"]
if "uids" not in keywords:
self.uids = d["uids"]
if self.pahdb:
if self.pahdb["database"] != self.database:
message(
f'DATABASE MISMATCH: {self.pahdb["database"]} != {self.database}')
return
if self.pahdb["version"] != self.version:
message(
f'VERSION MISMATCH: {self.pahdb["version"]} != {self.version}')
return
[docs]
def get(self) -> dict:
"""
Return data dictionary with expected keywords.
"""
return {
"type": self.__class__.__name__,
"database": self.database,
"version": self.version,
"data": self.data,
"uids": self.uids,
}
def __repr__(self) -> str:
"""
Class representation.
"""
return (
f"{self.__class__.__name__}("
f"{self.uids=},{self.database=},{self.version=})"
)
def __str__(self) -> str:
"""
A description of the instance.
"""
return f"AmesPAHdbPythonSuite Species instance.\n" f"{self.uids=}"
[docs]
def getuids(self) -> list[int]:
"""
Return uid list.
"""
return self.uids
[docs]
def intersect(self, uids: list[int]) -> None:
"""
Updates data to the intersection with provided UIDs.
Parameters:
uids : list of integers
"""
keep = set(self.uids) & set(uids)
count = len(keep)
if count == 0:
message("NO INTERSECTION FOUND")
return
message(f"INTERSECTION FOUND: {count}")
self.uids = list(keep)
self.data = {key: self.data[key] for key in self.uids}
[docs]
def difference(self, uids: list[int]) -> None:
"""
Updates data to the difference with provided UIDs.
Parameters:
uids : list of integers
List of UIDs.
"""
keep = set(self.uids) - set(uids)
count = len(keep)
if count == 0:
message("NO DIFFERENCE FOUND")
return
message(f"DIFFERENCE FOUND: {keep}")
self.uids = list(keep)
self.data = {key: self.data[key] for key in self.uids}
[docs]
def transitions(self) -> transitions.Transitions:
"""
Return transitions instance.
Calls the :class:`amespahdbpythonsuite.transitions.Transitions` class.
Returns:
transitions instance
"""
return transitions.Transitions(
database=self.database,
version=self.version,
data=self.__getkey("transitions"),
pahdb=self.pahdb,
uids=self.uids,
model={"type": "zerokelvin_m",
"temperature": 0.0, "description": ""},
units={
"abscissa": {
"unit": u.cm**-1,
"label": "frequency",
},
"ordinate": {"unit": u.km / u.mol, "label": "integrated cross-section"},
},
)
[docs]
def geometry(self) -> geometry.Geometry:
"""
Return geometry instance.
Calls the :class:`amespahdbpythonsuite.geometry.Geometry` class.
Returns:
geometry instance
"""
return geometry.Geometry(
database=self.database,
version=self.version,
data=self.__getkey("geometry"),
pahdb=self.pahdb,
uids=self.uids,
)
[docs]
def laboratory(self) -> Optional[laboratory.Laboratory]:
"""
Return laboratory instance.
Calls the :class:`amespahdbpythonsuite.laboratory.Laboratory` class.
Returns:
laboratory instance
"""
if self.data["database"] != "experimental":
message("EXPERIMENTAL DATABASE REQUIRED")
return None
return laboratory.Laboratory(
database=self.database,
version=self.version,
data=self.__getkey("laboratory"),
pahdb=self.pahdb,
uids=self.uids,
model={"type": "laboratory_m",
"temperature": 0.0, "description": ""},
units={
"abscissa": {"unit": 1, "str": "frequency [wavenumber]"},
"ordinate": {"unit": 2, "str": "absorbance" + "[-log(I/I$_{0})$"},
},
)
[docs]
def references(self) -> dict:
"""
Return dict with references.
Returns:
dict
"""
return self.__getkey("references")
def __getkey(self, key) -> dict:
"""
Get a dictionary of species properties
retrieved by keyword.
Parameters:
key : str
Database keyword.
Returns:
Dictionary of retrieved properties with UIDs as keys.
"""
return copy.deepcopy(
dict(
(uid, self.data[uid][key])
for uid in self.uids
if uid in self.data.keys()
)
)