Skip to content

Commit

Permalink
fixed HITRAN exact name
Browse files Browse the repository at this point in the history
  • Loading branch information
HajimeKawahara committed Dec 26, 2022
1 parent 96f89ff commit d52c66c
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 128 deletions.
2 changes: 1 addition & 1 deletion src/exojax/spec/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ def exact_isotope_name(self, isotope):
Returns:
str: exact isotope name such as (12C)(16O)
"""
from exojax.utils.isotopes import exact_hitran_isotope_name_from_isotope
from exojax.utils.molname import exact_hitran_isotope_name_from_isotope
return exact_hitran_isotope_name_from_isotope(self.simple_molecule_name,
isotope)

Expand Down
20 changes: 14 additions & 6 deletions src/exojax/spec/molinfo.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import warnings
from exojax.utils.isotopes import molmass_hitran
from exojax.utils.molname import e2s
from exojax.utils.isotopes import exact_molecule_name_to_isotope_number
from exojax.utils.molname import exact_molname_exomol_to_simple_molname
from exojax.utils.molname import exact_molecule_name_to_isotope_number
from exojax.utils.molname import exact_molname_hitran_to_simple_molname

def isotope_molmass(exact_molecule_name):
"""isotope molecular mass
Expand All @@ -13,11 +14,18 @@ def isotope_molmass(exact_molecule_name):
float or None: molecular mass g/mol
"""
molmass_isotope, abundance_isotope = molmass_hitran()
isotope_number = exact_molecule_name_to_isotope_number(exact_molecule_name)
if isotope_number is not None:
simple_molecule_name = e2s(exact_molecule_name)
molnumber, isotope_number = exact_molecule_name_to_isotope_number(exact_molecule_name)
try:
simple_molecule_name = exact_molname_exomol_to_simple_molname(exact_molecule_name)
return molmass_isotope[simple_molecule_name][isotope_number]
else:
except:
pass

try:
simple_molecule_name = exact_molname_hitran_to_simple_molname(exact_molecule_name)
return molmass_isotope[simple_molecule_name][isotope_number]
except:
warnings.warn("exact molecule name is not Exomol nor HITRAN form.")
warnings.warn("No molmass available", UserWarning)
return None

Expand Down
63 changes: 2 additions & 61 deletions src/exojax/utils/isotopes.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,55 +15,10 @@

import numpy as np
from exojax.utils import isodata
from exojax.utils import molname
import pkgutil
from io import BytesIO
import pandas as pd


def exact_molecule_name_to_isotope_number(exact_molecule_name):
"""Convert exact molecule name to isotope number
Args:
exact_molecule_name (str): exact exomol, hitran, molecule name such as 12C-16O, (12C)(16O)
Returns:
int: isotope number
"""
from radis.db.molparam import isotope_name_dict

#check exomol exact name
keys = [
k for k, v in isotope_name_dict.items() if v == exact_molecule_name
]
if len(keys) == 0:
#check hitran exact name
exact_hitran_molecule_name = exact_molname_exomol_to_hitran(
exact_molecule_name)
keys = [
k for k, v in isotope_name_dict.items()
if v == exact_hitran_molecule_name
]
if len(keys) == 1:
isotope_number = keys[0][1]
else:
print("No isotope number identified")
print("Report at https://github.com/HajimeKawahara/exojax/issues.")
return None

return isotope_number


def exact_molname_exomol_to_hitran(exact_exomol_molecule_name):
"""Convert exact_molname used in ExoMol to those in HITRAN
Args:
exact_exomol_molecule_name (str): exact exomol molecule name such as 12C-16O
Returns:
str: exact exomol molecule name such as (12C)(16O)
"""
return "(" + exact_exomol_molecule_name.replace("-", ")(") + ")"
from exojax.utils.molname import exact_molname_exomol_to_simple_molname


def molmass_hitran():
Expand Down Expand Up @@ -104,20 +59,6 @@ def molmass_hitran():
return molmass_isotope, abundance_isotope


def exact_hitran_isotope_name_from_isotope(simple_molecule_name, isotope):
"""exact isotope name from isotope (number)
Args:
simple_molecular_name (str): simple molecular name such as CO
isotope (int): isotope number starting from 1
Returns:
str: HITRAN exact isotope name such as (12C)(16O)
"""
from radis.db.molparam import MolParams
mp = MolParams()
return mp.get(simple_molecule_name, isotope, "isotope_name")


def get_isotope(atom, isolist):
"""get isotope info.
Expand All @@ -135,7 +76,7 @@ def get_isotope(atom, isolist):
mass_number = []
abundance = []
for j, isol in enumerate(isolist['isotope']):
if molname.e2s(isol) == atom:
if exact_molname_exomol_to_simple_molname(isol) == atom:
iso.append(isolist['isotope'][j])
mass_number.append(isolist['mass_number'][j])
abundance.append(float(isolist['abundance'][j]))
Expand Down
113 changes: 99 additions & 14 deletions src/exojax/utils/molname.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,80 @@
from radis.db.classes import get_molecule
import re
import warnings


def e2s(molname_exact):
def exact_hitran_isotope_name_from_isotope(simple_molecule_name, isotope):
"""exact isotope name from isotope (number)
Args:
simple_molecular_name (str): simple molecular name such as CO
isotope (int): isotope number starting from 1
Returns:
str: HITRAN exact isotope name such as (12C)(16O)
"""
from radis.db.molparam import MolParams
mp = MolParams()
return mp.get(simple_molecule_name, isotope, "isotope_name")


def exact_molecule_name_to_isotope_number(exact_molecule_name):
"""Convert exact molecule name to isotope number
Args:
exact_molecule_name (str): exact exomol, hitran, molecule name such as 12C-16O, (12C)(16O)
Returns:
int: molecular number, isotope number
"""
from radis.db.molparam import isotope_name_dict

#check exomol exact name
keys = [
k for k, v in isotope_name_dict.items() if v == exact_molecule_name
]
if len(keys) == 0:
#check hitran exact name
exact_hitran_molecule_name = exact_molname_exomol_to_hitran(
exact_molecule_name)
keys = [
k for k, v in isotope_name_dict.items()
if v == exact_hitran_molecule_name
]
if len(keys) == 1:
molnumber = keys[0][0]
isotope_number = keys[0][1]
else:
print("No isotope number identified")
print("Report at https://github.com/HajimeKawahara/exojax/issues.")
return None

return molnumber, isotope_number


def exact_molname_exomol_to_simple_molname(exact_exomol_molecule_name):
"""convert the exact molname (used in ExoMol) to the simple molname.
Args:
molname_exact: the exact molname
exact_exomol_molecule_name: the exact exomol molecule name
Returns:
simple molname
Examples:
>>> print(e2s("12C-1H4"))
>>> print(exact_molname_exomol_to_simple_molname("12C-1H4"))
>>> CH4
>>> print(e2s("23Na-16O-1H"))
>>> print(exact_molname_exomol_to_simple_molname("23Na-16O-1H"))
>>> NaOH
>>> print(e2s("HeH_p"))
>>> print(exact_molname_exomol_to_simple_molname("HeH_p"))
>>> HeH_p
>>> print(e2s("trans-31P2-1H-2H")) #not working
>>> print(exact_molname_exomol_to_simple_molname("trans-31P2-1H-2H")) #not working
>>> Warning: Exact molname trans-31P2-1H-2H cannot be converted to simple molname
>>> trans-31P2-1H-2H
"""

try:
t = molname_exact.split('-')
t = exact_exomol_molecule_name.split('-')
molname_simple = ''
for ele in t:
alp = ''.join(re.findall(r'\D', ele))
Expand All @@ -32,12 +83,46 @@ def e2s(molname_exact):
num = num0
else:
num = ''
molname_simple = molname_simple+alp+num
molname_simple = molname_simple + alp + num
return molname_simple
except:
print('Warning: Exact molname ', molname_exact,
print('Warning: Exact molname ', exact_exomol_molecule_name,
'cannot be converted to simple molname')
return molname_exact
return exact_exomol_molecule_name


def exact_molname_hitran_to_simple_molname(exact_hitran_molecule_name):
"""convert exact hitran molname (16C)(13C)(17O) to simple molname, CO2.
Args:
exact_hitran_molecule_name (str): exact_hitran_molecule_name, such as (16C)(13C)(17O)
Returns:
str: simple molecue name, such as CO2
"""
molnum, isonum = exact_molecule_name_to_isotope_number(
exact_hitran_molecule_name)
return get_molecule(molnum)


def exact_molname_exomol_to_hitran(exact_exomol_molecule_name):
"""Convert exact_molname used in ExoMol to those in HITRAN
Args:
exact_exomol_molecule_name (str): exact exomol molecule name such as 12C-16O
Returns:
str: exact exomol molecule name such as (12C)(16O)
"""
return "(" + exact_exomol_molecule_name.replace("-", ")(") + ")"


def e2s(exact_exomol_molecule_name):

warnings.warn(
"e2s will be replaced to exact_molname_exomol_to_simple_molname.",
DeprecationWarning)
return exact_molname_exomol_to_simple_molname(exact_exomol_molecule_name)


def split_simple(molname_simple):
Expand Down Expand Up @@ -68,7 +153,7 @@ def split_simple(molname_simple):
num = ''
tmp = ch
elif ch.islower():
tmp = tmp+ch
tmp = tmp + ch
elif ch.isdigit():
num = ch

Expand Down Expand Up @@ -98,9 +183,9 @@ def s2e_stable(molname_simple):
molname_exact = ''
for j, atm in enumerate(atom_list):
iso = isotopes.get_stable_isotope(atm, isolist)
molname_exact = molname_exact+iso[0]+num_list[j]
if j < len(atom_list)-1:
molname_exact = molname_exact+'-'
molname_exact = molname_exact + iso[0] + num_list[j]
if j < len(atom_list) - 1:
molname_exact = molname_exact + '-'
return molname_exact


Expand Down
4 changes: 2 additions & 2 deletions tests/unittests/atom/molmass_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

def test_molmass():
assert molmass_isotope('air')==28.97
assert molmass_isotope('CO2')==pytest.approx(44.00974325129166)
assert molmass_isotope('CO2')==pytest.approx(43.98983)
assert molmass_isotope('He')==4.002602
assert molmass_isotope('CO2',db_HIT=True)==44.00974325129166
assert molmass_isotope('CO2',db_HIT=True)==43.98983
assert molmass_isotope('He',db_HIT=True)==4.002602


Expand Down
3 changes: 2 additions & 1 deletion tests/unittests/spec/api/molinfo_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@


def test_isotope_molmass():
assert isotope_molmass("(12C)(16O)") == pytest.approx(27.994915)
assert isotope_molmass("12C-16O") == pytest.approx(27.994915)

def test_mean_molmass():
assert molmass_isotope("CO") == pytest.approx(28.01044518292034)
assert molmass_isotope("CO") == pytest.approx(27.994915)

if __name__ == "__main__":
test_isotope_molmass()
Expand Down
35 changes: 1 addition & 34 deletions tests/unittests/utils/isotopes_test.py
Original file line number Diff line number Diff line change
@@ -1,49 +1,18 @@
from exojax.utils.isotopes import get_isotope
from exojax.utils.isotopes import get_stable_isotope
from exojax.utils.isotopes import isodata
from exojax.utils.isotopes import exact_hitran_isotope_name_from_isotope
from exojax.utils.isotopes import molmass_hitran
from exojax.utils.isotopes import exact_molecule_name_to_isotope_number
from exojax.utils.isotopes import exact_molname_exomol_to_hitran
import numpy as np
import pytest



def test_exact_molecule_name_to_isotope_number():
eemn = "12C-16O"
isonum = exact_molecule_name_to_isotope_number(eemn)
assert isonum == 1
eemn = "16O-13C-17O"
isonum = exact_molecule_name_to_isotope_number(eemn)
assert isonum == 6


def test_exact_molname_exomol_to_hitran():
eemn = "16O-13C-17O"
ehmn = exact_molname_exomol_to_hitran(eemn)
assert ehmn == "(16O)(13C)(17O)"


def test_molarmass_hitran():
molmass_isotope, abundance_isotope = molmass_hitran()
assert molmass_isotope["CO"][1] == 27.994915
assert molmass_isotope["CO"][0] == pytest.approx(28.01044518292034) #mean
assert abundance_isotope["CO"][1] == pytest.approx(9.86544E-01)


def test_exact_isotope_name_from_isotope():
simple_molecule_name = "CO"
isotope = 1
assert exact_hitran_isotope_name_from_isotope(simple_molecule_name,
isotope) == "(12C)(16O)"

simple_molecule_name = "H2O"
isotope = 5
assert exact_hitran_isotope_name_from_isotope(simple_molecule_name,
isotope) == "HD(18O)"


def test_get_isotope():
isolist = isodata.read_mnlist()
ref = (['1H', '2H', '3H'], [1.007825, 2.014102,
Expand All @@ -62,7 +31,5 @@ def test_get_stable_isotope():
if __name__ == "__main__":
test_get_isotope()
test_get_stable_isotope()
test_exact_isotope_name_from_isotope()
test_molarmass_hitran()
test_exact_molname_exomol_to_hitran()
test_exact_molecule_name_to_isotope_number()

Loading

0 comments on commit d52c66c

Please sign in to comment.