Closed dreamalligator closed 6 years ago
Changing names
to a dictionary might be a good idea! That would solve the problem of someone who needs to dive in and select one particular name, or test for its presence. I do think it would be an improvement, so let’s make that change as part of this issue.
I do not see a license associated with the PyStarAtlas project, so we had better steer clear of including any of their code in Skyfield lest we compromise our own license.
Adding a new module to load the cross index is a good idea, and it can live in the data
directory next to hipparcos
. Instead of reading through the whole cross index for one star, I am tempted to either read the whole thing into RAM as a dictionary (depending on how big it is), or else have a conversion routine that will re-save it as a live sqlite3
database with indexing turned on so that particular stars can be looked up immediately without the user having to re-read the whole file for each one. Does that make sense?
The code you have pasted in will save me the trouble of learning to parse the file — thanks! Would you like to submit it (minus the excerpt from PyStarAtlas) as a skyfield/data/new_cross.py
file via a pull request so that you get credit for having put together this first version of the code?
Okay, I made the pull request. Among the changes, names
is now a dictionary. I named the file new_cross.py
, but of course feel free to change the name of the function to something other than new_cross
. I would have named it parse
like in hipparcos.py
but I didn't know if you wanted to make that a catalog convention or stay away from equivalent method names. I like your idea about loading the data into a database or RAM as a dictionary.
In the docs a note might be made on mixing catalogs. It is up to the programmer, but maybe suggest when setting my_star.names = new_cross('HIP',my_star.names['HIP'])
when my_star = hipparcos.get('25930')
. A quick my_star.names.pop('RA')
and my_star.names.pop('Dec')
would remove confusing the position data.
I didn't include the pystaratlas alphabet dictionary. Pystaratlas is GNU GPL v3. Would this function be an okay drop-in replacement? It handles any greek and number instead of hardcoding.
It follows the format found in the New Cross Index where two digits can be appended to the abbreviations.
Abbreviations for the greek letters (the same as in catalog Hipparcos):
alpha = alf beta= bet gamma= gam delta= del epsilon= eps
dzeta = zet eta = eta theta= the iota = iot kappa = kap
lambda= lam mu = mu. nu = nu. xi = ksi omicron= omi
pi = pi. rho = rho sigma= sig tau = tau upsilon= ups
phi = phi chi = chi psi = psi omega= ome
def greek(s):
a = {'alf':u'α','bet':u'β','gam':u'γ','del':u'δ','eps':u'ε','zet':u'ζ','eta':u'η','the':u'θ','iot':u'ι','kap':u'κ','lam':u'λ','mu.':u'μ','nu.':u'ν','ksi':u'ξ','omi':u'ο','pi.':u'π','rho':u'ρ','sig':u'σ','tau':u'τ','ups':u'υ','phi':u'φ','chi':u'χ','psi':u'ψ','ome':u'ω'}
n = u'⁰¹²³⁴⁵⁶⁷⁸⁹'
try:
letter = a[s[0:3]]
except:
return None
try:
letter = letter+n[int(s[3:5])]
except:
try:
letter = letter+n[int(s[3])]+n[int(s[4])]
except:
pass
#print(letter)
return letter
nu03 = greek('nu.03')
pi = greek('pi. ')
bet = greek('bet ')
# made these ones up to test no breakage for nontypical bayer formatted strings
psi47 = greek('psi47')
valid0 = greek('eta 7')
valid1 = greek('kap9 ')
valid2 = greek(' ')
invalid0 = greek(' 7')
invalid1 = greek(' 00')
print(nu03,pi,bet,psi47,valid0,valid1,valid2,invalid0,invalid1)
Output:
ν³
π
β
ψ⁴⁷
η⁷
κ⁹
(u'\u03bd\xb3', u'\u03c0', u'\u03b2', u'\u03c8\u2074\u2077', u'\u03b7\u2077', u'\u03ba\u2079', None, None, None)
Tests and Usage
from skyfield.data import new_cross
mintaka_names = new_cross.new_cross('HIP','25930')
print(mintaka_names)
Output:
{'HIP': ' 25930', 'DM': 'BD-00 983 ', 'Vmag': ' 2.25', 'HR': '1852', 'BFD': 'del ', 'GC': ' 6847', 'RA': <Angle 05deg 32' 00.4">, 'Cst': 'Ori', 'Bayer': 'del ', 'Dec': <Angle 00deg 17' 56.7">, 'Fl': ' 34', 'HD': ' 36486'}
Test that name is now by default an empty dict {}
.
from skyfield.starlib import Star
mystar = Star(ra_hours=5.5334446452722048, dec_degrees=-0.29909203888888819, ra_mas_per_year=1.67, dec_mas_per_year=0.56, parallax_mas=3.56)
mystar.names
I tested the modified hipparcos.get
using my version of the load
function https://github.com/brandon-rhodes/python-skyfield/pull/36.
from skyfield.data import hipparcos
star = hipparcos.get('25930')
print(star)
print(star.names['HIP'])
Output:
Star(ra_hours=5.5334446452722048, dec_degrees=-0.29909203888888819, ra_mas_per_year=1.67, dec_mas_per_year=0.56, parallax_mas=3.56, names={'HIP': 25930})
25930
This uses your Assay instead of Unittest right? After install what is the command to run these tests?
Thanks for letting me add this to the project :)
Hi.
I am Nacho Mas, the pystaratlas developer. Feel free to use anything of my code. I will be proud if could be usefull to improve your amazing work in any way.
Cheers
Thank you, @nachoplus, for your permission! I will be sure to give credit if we re-use any code.
@digitalvapor — I have been busy adding Jovian moon support to Skyfield, but have kept star names in the back of my mind, and am trying to think of a way around a dict-per-star. I am thinking of people who might load up millions of stars to do detailed finder charts and things like that. Is that a silly case to think about? I mean, no one ever puts millions of stars on a single printed page — the number of objects shown on a page is always in, what, the hundreds at most?
Anyway, I want to make sure that loading up a huge star atlas and selecting stars by name, or of filtering for the stars that belong in a particular image, is effective, and I'll hopefully have more ideas about that by the time that I get done with the Jovian moons.
@brandon-rhodes I don't think that is silly at all. One of my projects is using IPHAS with Skyfield. Although I definitely won't be naming these stars, I see the potential. If I were to name proper-named/Bayer-designated stars, then I'd have duplicate indexes. Please keep mulling that over :+1:
I've finally come up with a way to handle big star catalogs, and have commented on the pull request about the approach. Since there's now a way forward I'm going to remove myself from this issue until we finish over on the pull request. Good luck, and thanks!
thanks!
The New Cross Index (IV/27A) could be used to populate the Star name. The particular instance I wanted to use this was to look up both the Bayer designation and visual magnitude using the Hipparcos number.
s.names
is currently[('HIP', 25930)]
.Dictionary of names returned that matches the Hipparcos number 25930
And the Bayer designation
'\xce\xb4'
=δ
.My apologies for all the issues this week. I've just been integrating Skyfield into a project and it has been useful enough that I've read through the code a few times :).
What do you think of instead of setting
names=[('HIP','25930')]
, the format could be a dictionary with the catalog abbreviation as the key? Or of course left as is. The function could possibly be used as a standalone method, or in a Star class method. If used internally with the Hipparcos functions, since position is already populated, the values ofRA
andDec
should be popped out so that there arent duplicates like in the above example.If this fits in with what you want for Skyfield, let me know and I can make a pull request for it.