Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions docs/getting_started.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

Getting started
===============

.. code-block:: python

import opacity
import matplotlib.pyplot as plt

dataset = opacity.open_dataset('VO')

select = dict(
temperature=750, # [K]
pressure=1e-5 # [bar]
)
cross_section = dataset.cross_section.sel(select)
metadata = cross_section.attrs

fig, ax = plt.subplots(figsize=(10, 5), dpi=300)
ax.loglog(ds.wavenumber, cross_section)

title = (
f"{metadata['molecule']}, "
f"T={select['temperature']} {cross_section.temperature.unit}, "
f"P={select['pressure']} {cross_section.pressure.unit}"
)

ax.set(
ylim=(1e-40, 1e-10),
xlabel=f"Wavenumber [{cross_section.wavenumber.attrs['unit']}]",
ylabel=f"Cross section [{metadata['unit']}]",
title=title
)
1 change: 1 addition & 0 deletions opacity/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
from opacity.dataset import *
from opacity.filesystem import *
from opacity.resolve_species import *
from opacity.metadata import *
85 changes: 85 additions & 0 deletions opacity/data/metadata_descriptions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{
"calculation": {
"entries": {
"id": "int",
"mol": "str",
"iso_mol": "str",
"iso_abundance": "dict",
"ptid": "int",
"temperature": "float",
"pressure": "float",
"intensity_cutoff": "float",
"wing_cutoff": "float",
"line_profile": "float",
"code": "str",
"start_wno": "float",
"delta_wno": "float",
"doi": "str",
"date": "str"
}
},
"broadening": {
"calculation_options": {
"P_bro(J)": {
"full_name": "Used one equation for all transitions",
"description": "A single equation for the all lines which shows the behavior of P-broadening with quantum number J. This assumes the impact of molecular symmetry, other quantum numbers, and vibrational quantas are ignored in the general (P_{bro}(J)) equation form. "
},
"P_bro(J,Vib)": {
"full_name": "Used N equations for a molecule with N vibrational quanta",
"description": "N equations to describe the behavior of pressure-broadening coefficients for all lines based on their vibrational quanta and J quantum numbers. Therefore, for H2O molecule, we expect to have one equation for all Js, and multiple equations for each vibrational bands. This assumes the impact of other quantum numbers, and molecular symmetry are ignored in this (P_{bro}(J, vib)) equation form. "
},
"P_bro(J,sym)": {
"full_name": "Used N equations for a molecule with N symmetries",
"description": "N equations to describe the behavior of pressure-broadening coefficients for all lines based on their molecular symmetry and J quantum number.For example, (P_{bro}(J,Sym_1)= m_0 + (m_1*J) + (m_2*J^2)); (P_{bro}(J,Sym_2)= m_3 + (m_4*J) + (m_5*J^2)); etc. Assumptions: The impact of other quantum numbers and vibrational quantas are ignored in this (P_{bro}(J, Sym)) equation form. "
},
"P_bro(J,K,sym)": {
"full_name": "Used N equations for a molecule with N symmetries, and K molecular symmetries",
"description": "N equations to describe the behavior of pressure-broadening coefficient for all lines based on their symmetry, J and K quantum numbers. For example, (P_{bro}(J,Sym_1)=m_0+(m_1*J)+(m_2*J^2)+(n_1*K)+(n_2*K^2)), and (P_{bro}(J,K, Sym_2)=m_3+(m_4*J)+(m_5*J^2)+(n_3*K)+(n_4*K^2)), etc. Assumptions: The impact of vibrational quantas is ignored in this (P_{bro}(J,K, Sym)) equation form. "
},
"P_bro(J,K,sym,Vib)": {
"full_name": "Used N*M equations for a molecule with N symmetries, and M vibrational bands",
"description": "This equation accounts for the dependency of P-broadening on the quantum numbers J and K, molecular symmetries, and also vibrational bands. For example: (P_{bro}(J,K, Sym_1, Vib_1)=m_0+(m_1*J)+(m_2*J^2)+(n_1*K)+(n_2*K^2)), and (P_{bro}(J,K, Sym_2, Vib_2)=m_3+(m_4*J)+(m_5*J^2)+(n_3*K)+(n_4*K^2))."
},
"P_bro(lab,theory)": {
"full_name": "Used laboratory data and theoretical equations",
"description": "A set of laboratory measurmed coefficients and theoretical calculated P-broadening data just as they are."
}
},
"usr_warnings": {
"1":"Laboratory or theoretical broadener information not available at all.",
"2":"Theoretical broadener information used is for 296 K. Functional extrapolation used.",
"3":"Broadener data for an air mixture was used in place of this broadener gas.",
"4":"Broadener data is incomplete for high values of J",
"5":"Broadener data for self broadening was used in place of this broadener gas.",
"6":"Average values (non J-dependent) for the line broadening parameters are used."
},
"entries": {
"broadened_by": "str",
"abundance": "float",
"calculation_type": "str",
"functional_form": "str",
"inputs": "list",
"bibid": "str",
"usr_warning": "int",
"usr_note": "str",
"todo": "str"
}
},
"line_list": {
"entries": {
"wno_min": "float",
"wno_max": "float",
"temp_min":"float",
"temp_max":"float",
"db_name": "str",
"bibid": "str",
"usr_warning": "str",
"usr_note": "str",
"todo": "str"
},
"usr_warnings": {
"1": "Line list used is not suitable for this temperature regime.",
"2": "The line position accuracy is suitable for JWST-quality spectra only (R=100-3000)."
}
}
}
152 changes: 152 additions & 0 deletions opacity/metadata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import os
import re
import json
from pathlib import Path

import ipywidgets
from IPython.display import display, Javascript
import solara

__all__ = ['Metadata']

tab_style = {
'text-transform': 'capitalize'
}
value_style = {
'padding-left': '8em',
'padding-top': '0.5em',
'padding-bottom': '0.5em',
}


metadata_desc_path = os.path.join(
os.path.dirname(__file__),
'data',
'metadata_descriptions.json'
)

with open(metadata_desc_path, 'r') as meta:
metadata_desc = json.load(meta)


def copy_button(text):
output = ipywidgets.Output()

def on_button_click(_, text=text):
with output:
output.clear_output()
display(Javascript(f'navigator.clipboard.writeText("{text}")'))

button = ipywidgets.Button(description="", icon="copy")
button.on_click(on_button_click)
button.layout.width = '30pt'
button.layout.font_size = '1pt'
button.style.button_color = "transparent"
button.style.text_color = "#037ffc"

return ipywidgets.HBox([button, output])


def unpack_dict(d):
tab_order = [
'linelist', 'calculation', 'broadener_H2',
'broadener_He', 'compression', 'source',
]
for tab_key, tab_value in d.items():
if tab_key in ['molecule', 'unit']:
continue

if tab_key in tab_order:
with solara.lab.Tab(f"{tab_key}", style=tab_style):
with solara.Div(style={'padding-left': '3em'}):
unpack_dict(tab_value)
continue

else:
if tab_key == 'todo' or tab_value == '':
continue

solara.Markdown(f"#### {tab_key}")

if tab_key.startswith('calculation_type'):
desc = metadata_desc['broadening']['calculation_options'][tab_value]['description']
solara.Markdown(f"{desc}", style={'color': '#5A5A5A'})

with solara.Row(margin=0):

if tab_key.startswith('usr_warning'):
if tab_value == 0:
solara.Markdown("No warnings.", style=value_style)
else:
desc = metadata_desc['broadening']['usr_warnings'][str(tab_value)]
solara.Markdown(f"{desc} ({tab_value})", style=value_style)
else:
value_markdown, copy_text = to_markdown(tab_value)
solara.Markdown(
value_markdown,
style=value_style
)
if copy_text:
# with solara.Tooltip("Markdown", color="white"):
solara.display(copy_button(copy_text))


def to_markdown(text):
text_href_markdown, href_url = latex_href_to_markdown(str(text))
text_markdown, doi_url = doi_to_markdown(text_href_markdown)

if href_url is not None:
copy_text = href_url
elif doi_url is not None:
copy_text = doi_url
elif '$' in text_markdown or text_markdown.startswith('['):
copy_text = text_markdown
else:
copy_text = None

return str(text_markdown), copy_text


def latex_href_to_markdown(text):
if not isinstance(text, str) or 'href' not in text:
return text, None

pattern = r"\\href\{([^}]*)\}\{([^}]*)\}"
replacement_html = r'<a href=\1 target="_blank">\2</a>'
replacement_markdown = r"[\2](\1)"
return (
re.sub(pattern, replacement_html, text),
re.sub(pattern, replacement_markdown, text)
)


def doi_to_markdown(text):
if not isinstance(text, str) or 'DOI' not in text:
return text, None

pattern = r"DOI=\[(.*?)\]"
replacement_html = r'<a href=https://doi.org/\1 target="_blank">\1</a>'
replacement_markdown = r'[\1](https://doi.org/\1)'
return (
re.sub(pattern, replacement_html, text),
re.sub(pattern, replacement_markdown, text)
)


@solara.component
def Metadata(cross_section):
solara.Markdown(f"## Metadata: {cross_section.attrs['molecule']}")
with solara.lab.Tabs(
vertical=True, lazy=True, color="#C5F8FD",
dark=True, background_color="#13457B",
slider_color="#A0F7FF"
):
tab_order = [
'linelist', 'calculation', 'broadener_H2',
'broadener_He', 'compression', 'source',
]
dictionary = {
ordered_key: cross_section.attrs[ordered_key]
for ordered_key in tab_order
}
unpack_dict(dictionary)
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ dependencies = [
"s3fs",
"xarray",
"zarr",
"ipywidgets",
"IPython",
"solara",
]
dynamic = ["version"]

Expand Down
Loading