Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add numerical conversions to SpectralType class #44

Merged
merged 1 commit into from
Sep 12, 2024
Merged
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
32 changes: 31 additions & 1 deletion astar_utils/spectral_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,44 @@ def __str__(self) -> str:
f"{self.luminosity_class or ''}")
return spectype

@property
def _spec_cls_idx(self) -> int:
return self._cls_order.index(self.spectral_class)

@property
def numerical_spectral_class(self) -> float:
"""Spectral class and subclass as float for better interpolations.

Main spectral class is converted to its index in the OBAFGKM range
multiplied by 10, i.e. ``O -> 0``, ``B -> 10``, ..., ``M -> 60``.

Spectral Subclass (already a float) is added as-is, resulting in an
output value between 0.0 (O0) and 69.9 (M9.9).

This can be easily reversed by taking the ``divmod`` of the resulting
float value by 10 to get the original OBAFGKM index and subclass, e.g.
``divmod(53.5, 10) -> 5, 3.5 -> K3.5``.
"""
return self._spec_cls_idx * 10. + (self.spectral_subclass or 0.)

@property
def numerical_luminosity_class(self) -> float:
"""Roman luminosity class converted to arabic number.

If no initial luminosity class was given, assume main sequence (V).
"""
if self.luminosity_class is None:
return 5 # assume main sequence if not given
return ("I", "II", "III", "IV", "V").index(self.luminosity_class) + 1

@property
def _comp_tuple(self) -> tuple[int, float]:
# if None, assume middle of spectral class
if self.spectral_subclass is not None:
sub_cls = self.spectral_subclass
else:
sub_cls = 5
return (self._cls_order.index(self.spectral_class), sub_cls)
return (self._spec_cls_idx, sub_cls)

def __lt__(self, other) -> bool:
"""Return self < other."""
Expand Down
14 changes: 14 additions & 0 deletions tests/test_spectral_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,20 @@ def test_str(self, ssl_cls, exptcted):
spt = SpectralType(ssl_cls)
assert str(spt) == exptcted

@pytest.mark.parametrize(("ssl_cls", "exptcted"),
[("A0V", 20), ("G2", 42), ("K9.0", 59),
("B2.7", 12.7), ("M3.1III", 63.1), ("KII", 50),])
def test_num_spec_cls(self, ssl_cls, exptcted):
spt = SpectralType(ssl_cls)
assert spt.numerical_spectral_class == exptcted

@pytest.mark.parametrize(("ssl_cls", "exptcted"),
[("A0V", 5), ("G2", 5), ("K9.0", 5), ("M4IV", 4),
("B2II", 2), ("M3.1III", 3), ("KII", 2),])
def test_num_lum_cls(self, ssl_cls, exptcted):
spt = SpectralType(ssl_cls)
assert spt.numerical_luminosity_class == exptcted


class TestUpperLowerCase:
def test_uppers_lower_case(self):
Expand Down