"""
BSC5Stars - a wrapper for The Yale Bright Star Catalog, 5th Edition (BSC5).
"""
import numpy as np
from astropy.coordinates import SkyCoord
from .StarCatalog import StarCatalog
[docs]
class BSC5Stars:
"""
BSC5Stars - a wrapper for The Yale Bright Star Catalog, 5th Edition (BSC5).
:param max_mag: Maximum star magnitude to process.
:type max_mag: float
The Bright Star Catalog, 5th Revised Edition (BSC5) lists all objects down to a limiting apparent visual magnitude of 6.5.
This cutoff corresponds to the limit of naked-eye visibility under clear, dark skies.
https://en.wikipedia.org/wiki/Bright_Star_Catalogue
In reality there are stars down to a magnitude of 8.0 in the catalog.
"""
def __init__(self, max_mag=4.0):
"""
BSC5Stars - a wrapper for The Yale Bright Star Catalog, 5th Edition (BSC5).
:param max_mag: Maximum star magnitude to process.
:type max_mag: float
"""
self._sc = StarCatalog('BSC5', use_database=True, force_reload=False, debug=False)
self._stars = None
self._skycoords = None
self._max_mag = max_mag
self._stars_ra_rad = []
self._stars_dec_rad = []
self._stars_mag = []
self._const_ra_rad = []
self._const_dec_rad = []
self._const_mag = []
def _proceess_stars(self):
""" _proceess_stars """
if self._stars is not None:
# done already
return
self._stars = self._sc.select_max_mag(self._max_mag)
def _proceess_skycoords(self):
""" _proceess_skycoords """
if self._skycoords is not None:
# done already
return
self._proceess_stars()
# Use ICRS as there's no time represented
self._skycoords = SkyCoord([(v.ra,v.dec) for v in self.stars], unit='rad', frame='icrs')
def __len__(self):
""" __len__ """
self._proceess_stars()
return len(self._stars)
def __array__(self, dtype=None):
"""Allows np.array(instance) to work."""
self._proceess_stars()
return np.array(self._stars, dtype=dtype)
@property
def max_mag(self):
"""
max_mag - get maximum magnitude.
:return: Maximum star magnitude to process.
:rtype: float
"""
return self._max_mag
@max_mag.setter
def max_mag(self, value):
"""
max_mag - set maximum magnitude.
:param max_mag: Maximum star magnitude to process.
:type max_mag: float
"""
if self._max_mag == value:
return
self._max_mag = value
# now reset everything!
self._stars = None
self._skycoords = None
self._stars_ra_rad = []
self._stars_dec_rad = []
self._stars_mag = []
self._const_ra_rad = []
self._const_dec_rad = []
self._const_mag = []
@property
def stars(self):
"""
stars - return an array of stars.
:return: array of stars.
:rtype: list[Stars]
"""
self._proceess_stars()
return self._stars
@property
def vector(self):
"""
vector - return an array of stars as a vector
"""
xyz = self.skycoords.cartesian.xyz.value
return xyz.T # shape (N,3)
@property
def skycoords(self):
"""
skycoords - return an array of stars (in SkyCoord format).
:return: array of stars in SkyCoord format.
:rtype: list[SkyCoord]
"""
self._proceess_skycoords()
return self._skycoords
[docs]
def get_stars(self):
""" get_stars - return an array of stars.
:return: array of stars.
:rtype: np.array
"""
self._precompute_stars()
return np.array(self._stars_ra_rad), np.array(self._stars_dec_rad), np.array(self._stars_mag)
[docs]
def get_constellations(self, constellations=None):
"""
get_constellations - return an array of constellations.
:param constellations: Which constellations to return.
:type constellations: list
:return: array of constellations.
:rtype: np.array
"""
if constellations is None:
constellations = ['Ori','Sgr']
self._precompute_constellation(constellations)
return np.array(self._const_ra_rad), np.array(self._const_dec_rad), np.array(self._const_mag)
def _precompute_stars(self):
""" _precompute_stars """
if len(self._stars_ra_rad) > 0:
return
self._stars_ra_rad = []
self._stars_dec_rad = []
self._stars_mag = []
for star in self.stars:
self._stars_ra_rad.append(star.ra)
self._stars_dec_rad.append(star.dec)
self._stars_mag.append(star.mag)
def _precompute_constellation(self, constellations):
""" _precompute_constellation """
if len(self._const_ra_rad) > 0:
return
self._const_ra_rad = []
self._const_dec_rad = []
self._const_mag = []
for star in self.stars:
if star.constellation not in constellations:
continue
self._const_ra_rad.append(star.ra)
self._const_dec_rad.append(star.dec)
self._const_mag.append(star.mag)
def _main(args=None):
""" _main """
b = BSC5Stars(max_mag=3.0)
for s in [b.stars, b.skycoords, b.vector]:
print('[')
for ii in range(5):
print('\t'+str(s[ii]).replace('\n', ' ')+',')
print(']')
print('')
b.max_mag = 9.0
t = len(b)
print('%6s %6s %6s' % ('MAG', 'COUNT', '%'))
for max_mag_int in range(-20,90,5):
b.max_mag = max_mag_int/10.0
print('%6.1f %6d %5.1f%%' % (b.max_mag, len(b.get_stars()[0]), (len(b)/t)*100.0))
#[
# Star(number=2491, name='9Alp', constellation='CMa', ra=1.7677930939085398, dec=-0.29175117701809655, mag=-1.46),
# Star(number=7001, name='3Alp', constellation='Lyr', ra=4.87356286460115, dec=0.6769017097019452, mag=0.03),
# Star(number=1708, name='13Alp', constellation='Aur', ra=1.3818208020352105, dec=0.802817518959714, mag=0.08),
# Star(number=1713, name='19Bet', constellation='Ori', ra=1.3724323851005242, dec=-0.14314608748440158, mag=0.12),
# Star(number=2943, name='10Alp', constellation='CMi', ra=2.0040815858077057, dec=0.09119345341670373, mag=0.38),
#]
if __name__ == '__main__':
_main()