solution_031b.py

#!/usr/bin/python3
# ===================================================================
# Read an ASCII star catalog data file, extract the star's galactic
# lat/lon and double/multi-star code
# convert lat/lon to X,Y,Z coordinates
# also do a little error checking (valid lat/lon?)
#
# output two  files:
# 1. write X,Y,Z and code to CSV file   (one line, one star)
# 2. write lat/lon and code to CSV file (one line, one star)
# ===================================================================

import sys
import user_interface as ui
from math import radians, sin, cos

dmsdck  = {}                   # double/multiple-star counts
ecount   = 0                   # errors count
icount   = 0                   # input  line count
ocount   = 0                   # output line count
infile   = 'bsc5.dat'          # input  file
outfile1 = 'bsc5.csv'          # output file 1
outfile2 = 'bsc5.llc'          # output file 2

# -------------------------------------------------------------------
# ---- convert galactic lat/lon to xyz
# -------------------------------------------------------------------

def lat_lon_to_xyz(lat,lon):

    rlat = radians(lat)        # convert to radians
    rlon = radians(lon)        # convert to radians

    x = sin(rlon) * cos(rlat)
    y = sin(rlat)
    z = cos(rlon) * cos(rlat)

    return (x,y,z)

# -------------------------------------------------------------------
# ---- main
# -------------------------------------------------------------------

ifile = open(infile,'r')

o1file = open(outfile1,'w')
o2file = open(outfile2,'w')

# process each line in the file

for line in ifile:

    # ---- strip '\r\n' characters from the end of the line

    line = line.rstrip('\r\n')

    icount += 1                # increment input line count

    # ---- get star's galactic latitude/longitude

    glat = line[96:102].strip()
    glon = line[90:96].strip()

    tf1,flat = ui.is_float(glat)
    tf2,flon = ui.is_float(glon)

    if not tf1 or not tf2:
        print(f'Input file error - line {icount:<5}',end='')
        print(f' glat = ({glat})  glon = ({glon})')
        ecount += 1
        if ecount > 20:        # to many errors?
            sys.exit()
        continue

    # ---- convert star's lat/lon to X,Y,Z

    xyz = lat_lon_to_xyz(flat,flon)


    # ---- count double/multiple-star codes

    code = line[43]            # double/multiple-star code

    if code in dmsdck.keys():
        dmsdck[code] += 1
    else:
        dmsdck[code] = 1

    # ---- write star's X,Y,Z coordinates and
    # ---- double/multiple-star code

    if code == ' ':           # output empty string and not
        code = ''             # a blank character

    o1file.write(f'{xyz[0]},{xyz[1]},{xyz[2]},{code}\n')

    # ---- write star's galactic lat/lon and
    # ---- double/multiple-star code

    o2file.write(f'{flat},{flon},{code}\n')

    # ---- count output

    ocount += 1                # increment output line count

# ---- end of program

ifile.close()
o1file.close()
o2file.close()

print()
print(f'{icount:6} lines input')
print(f'{ecount:6} lines with errors')
print(f'{ocount:6} lines output')
print('double/multiple-star code counts')
for k,v in dmsdck.items():
    print(f'[{k}] {v:4} entries in star catalog') 
print()