#!/usr/bin/python # identify.py # An asteroid_server client which identifies measurements in MPC format # Jure Skvarc, March 1999 # import socket import select from sys import * from string import * from math import * import getopt import os import errno import fileinput #=========================================================================== # Define a class to access asteroid_server #=========================================================================== class Asteroid_client: # Create a socket def __init__(self, host, port): self.port = port self.host = host self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) def connect(self): err = self.sock.connect_ex(self.host, self.port) # If connection did not succeed, exit if err != 0: print 'Can not connect to server', host, 'at port', port print 'Reason:', os.strerror(err) exit() def get(self): return self.sock.recv(1024) def send(self, request): self.sock.send(request) def close(self): self.sock.close() def get_answer(self, timeout): ins = 1 ans = '' # The answer may be pretty long, so be ready to receive in parts while ins: # Wait for the information a, b, c = select.select([self.sock], [], [], 10) if len(a) > 0: ans1 = self.get() if len(ans1) == 0: ins = 0 ans = ans + ans1 if ans[-1] == '\0': ins = 0 else: # Timeout, end the loop ins = 0 return ans #==================================== # class which holds coordinate pairs #==================================== class coorpair: pass #=========================================================================== # Extract hour from the decimal day and output hours in hh:mm:ss.ss format #=========================================================================== def tohours(day): day = day - int(day) hours = int(24 * day) day = 24 * day - hours minutes = int(60 * day) day = 60 * day - minutes seconds = 60 * day return "%02d:%02d:%05.2f" % (hours, minutes, seconds) #=========================================================================== # Translate designation to packed designation #=========================================================================== def designation_to_packed(name): packed = '' year, code = split(name) year = atoi(year) # Does it look like a year? if find(code, 'P-L') > 0 or find(code, 'T-1') > 0 or find(code, 'T-2') > 0 or find(code, 'T-3') > 0: packed = "%c%cS%4s" % (name[5], name[7], year) elif year > 1900 and year < 2100: cent = chr(year / 100 - 19 + ord('J')) num = atoi(code[2:]) if num < 100: n1 = chr(num / 10 + ord('0')) else: n1 = chr(num / 10 - 10 + ord('A')) n2 = chr(num % 10 + ord('0')) packed = "%c%02d%c%c%c%c" % (cent, year % 100, code[0], n1, n2, code[1]) return packed # Calculate the value of the haversine function def hav(x): x = sin(0.5 * x) return x * x # Inverse haversine function def invhav(x): return 2.0 * asin(sqrt(x)) #=================================================== # Calculate the angular distance between two points #=================================================== def angular_distance(ra1, dec1, ra2, dec2): return invhav(hav(dec1 - dec2) + cos(dec1) * cos(dec2) * hav(ra1 - ra2)) # Counter for the unknown asteroids astcount = 1 # Prefix for the unknown asteroids prefix = 'TT' # Whether to send the prepare command prepare = 0 prevdist = 120 #========================== # The program begins here #========================== #==================== # First get options #==================== try: optlist, args = getopt.getopt(argv[1:], 'p:n:d:', ['prefix=', 'number=', 'prevdist=']) except getopt.error, err: print 'Wrong option!', err exit(1) for a in optlist: if a[0] == '-p': prefix = a[1] elif a[0] == '-n': astcount = int(float(a[1])) elif a[0] == '-d': prevdist = a[1] else: prepare = 1 #========================================== # Check if enough arguments are specified #========================================== if len(args) < 5: print "Usage:: python [options] identify.py server_address id input_file distance magnitude" exit(1) # Default host address host = args[0] # User id id = args[1] # Input file name filename = args[2] # maximal acceptable distance to the object distance = atof(args[3]) # maximum acceptable magnitude of the object magnitude = atof(args[4]) # Port number for the astreoid server port = 58972 # try to connect to the server clnt = Asteroid_client(host, port) clnt.connect() # send id clnt.send(id + '\0') # Get an intro message hello = clnt.get() # Close the connection clnt.close() del clnt clnt = Asteroid_client(host, port) clnt.connect() # send id clnt.send(id + '\0') # Get an intro message hello = clnt.get() # List of coordinates of all asteroids coords = [] for line in fileinput.input(filename): if len(line) < 80: print line, continue a = line[0:11] a = strip(a) year = atoi(line[15:19]) month = atoi(line[20:22]) day = atof(line[23:31]) rah = atoi(line[32:34]) ram = atoi(line[35:37]) ras = atof(line[38:43]) dsign = line[44:45] dech = atoi(line[45:47]) decm = atoi(line[48:50]) decs = atof(line[51:55]) hour = tohours(day) query = "check \"%d %d %d %s\" %02d:%02d:%05.2f %s%02d:%02d:%04.1f %f %f\n" % \ (year, month, day, hour, rah, ram, ras, dsign, dech, decm, decs, distance, magnitude) ra = 15.0 * (rah + (ram + ras / 60.0) / 60.0) * 1.74532925199e-2 dec = (dech + (decm + decs / 60.0) / 60.0) * 1.74532925199e-2 if dsign == '-': dec = -dec query = query + '\0' # print query, clnt.send(query) list = clnt.get() # Find the object with the smallest distance mdist = distance * 60 lines = split(list, '\n') b = 'nothing' for a in lines: if len(a) <= 1: continue # print a dist = atof(split(a)[-1]) if dist < mdist: b = a mdist = dist line = 13 * ' ' + line[13:] discovery = ' ' if b == 'nothing': # There were no asteroids found within the given distance # Check if any of the previously processed asteroids is close to this one # (within 2 arcminutes) for p in coords: dist = angular_distance(p.ra, p.dec, ra, dec) * 206264.806247 if dist < prevdist: desig = p.desig break else: # Construct a new temporary designation desig = prefix + ("%04d" % astcount) astcount = astcount + 1 discovery = '*' desig = desig + ' ' line = line[0:5] + desig[0:7] + discovery + line[13:] else: num = atoi(strip(b[0:6])) if num == 0: desig = designation_to_packed(b[6:25]) line = line[0:5] + desig + line[12:] else: desig = ("%05d" % num) line = desig + line[5:] as = coorpair() as.ra = ra as.dec = dec as.desig = desig coords.append(as) print '%s' % line, clnt.close() exit(0)