#!/usr/bin/python3 # Demo to retrieve targets from NEOfixer, as well as other information about the targets. - A. R. Gibbs # From: https://neofixer.arizona.edu/api-info # Standard modules. import sys import json import argparse import requests # Version of this program. sVersion = '1.0 2022-06-14' # Default NEOfixer site name. You can change this to yours. sSite = 'I52' # Setup command line arguments, help, and defaults. oParse = argparse.ArgumentParser (description = 'Get targets from NEOfixer. All arguments are optional. In the descriptions below the units are enclosed in () and the defaults are enclosed in []. Switches with two arguments are ranges from the first value (min) to the second value (max) and pass values >= min and < max. See the NEOfixer API documentation for more details. Version: ' + sVersion, add_help = False) oSelect = oParse.add_argument_group ('Target selection') oSelect.add_argument ('-s', dest = 'site', default = sSite, help = 'Site code [' + sSite + ']') oSelect.add_argument ('-n', dest = 'num', type = int, default = 40, help = 'Number of objects [40]') oSelect.add_argument ('-o', dest = 'objs', metavar = 'ID', nargs = '+', help = 'Get specific object(s), ignoring filters [None]') oSelect.add_argument ('-A', dest = 'all', action='store_true', help = 'All targets, ignoring all filters [False]') oSelect.add_argument ('-U', dest = 'url', default = None, help = 'Use URL to get targets instead of command line filters. This could be an "API Link" from the website. [None]') oFilter = oParse.add_argument_group ('Target characteristics') oFilter.add_argument ('-c', dest = 'cost', type = float, nargs = 2, default = [0, 300], help = 'Cost (minutes) [0 300]') oFilter.add_argument ('-S', dest = 'score', type = float, nargs = 2, default = [0, 20], help = 'NEOfixer score [0 20]') oFilter.add_argument ('-m', dest = 'mag', type = float, nargs = 2, default = [0, 99], help = 'Magnitudes: brightest then faintest (V) [0 99]') oFilter.add_argument ('-r', dest = 'rate', type = float, nargs = 2, default = [0, 100000], help = 'Rates ("/min) [0 100000]') oFilter.add_argument ('-u', dest = 'uncert', type = float, nargs = 2, default = [0, 15], help = 'Uncertainty, 1-sigma (degrees) [0 15]') oFilter.add_argument ('-g', dest = 'gc', type = float, nargs = 2, default = [0, 25], help = 'Galactic confusion (0-100) [0 25]') oFilter.add_argument ('-R', dest = 'ra', type = float, nargs = 2, default = [0, 360], help = 'R.A. (decimal deg) [0 360]') oFilter.add_argument ('-D', dest = 'dec', type = float, nargs = 2, default = [-90, 90], help = 'Dec (decimal deg) [-90 90]') oDebug = oParse.add_argument_group ('Other') oDebug.add_argument ('-h', '--help', action='help', help = 'Display this help message and exit [False]') # Parse command line arguments. oArgs = oParse.parse_args () if oArgs.num < 1: print ('Number of objects to return must be > 0.') exit (1) print ("NEOfixer target list for " + oArgs.site + ".", file=sys.stderr) # Make the NEOfixer API URL. sBaseURL = 'https://neofixerapi.arizona.edu' try: # If user supplied a URL on the command line with -U then use that. if oArgs.url != None: sURL = oArgs.url # Else if user wants specific target(s) using -o then ask for all visible targets to find match(es). elif oArgs.objs != None or oArgs.all: sURL = sBaseURL + '/targets/?site=' + oArgs.site + '&all=1' # Else get targets using the supplied filters. else: print ("Getting up to " + str (oArgs.num) + " highest scoring targets that pass filters. Change num with -n.") sURL = sBaseURL + '/targets/?site=' + oArgs.site + '&num=' + str (oArgs.num) + '&vmag-bright=' + str (oArgs.mag[0]) + '&vmag-faint=' + str (oArgs.mag[1]) + '&cost-min=' + str (oArgs.cost[0]) + '&cost-max=' + str (oArgs.cost[1]) + '&score-min=' + str (oArgs.score[0]) + '&score-max=' + str (oArgs.score[1]) + '&rate-min=' + str (oArgs.rate[0]) + '&rate-max=' + str (oArgs.rate[1]) + '&uncert-min=' + str (oArgs.uncert[0]) + '&uncert-max=' + str (oArgs.uncert[1]) + '&gc-min=' + str (oArgs.gc[0]) + '&gc-max=' + str (oArgs.gc[1]) + '&dec-min=' + str (oArgs.dec[0]) + '&dec-max=' + str (oArgs.dec[1]) + '&ra-start=' + str (oArgs.ra[0]) + '&ra-stop=' + str (oArgs.ra[1]) # Uncomment next line to see the URL being used. # print ("\nAPI URL used: " + sURL, file=sys.stderr) # Prepare for reliably retrieving data from the NEOfixer API. # This can be done more simply but a bit less reliably. See the API documentation: https://neofixer.arizona.edu/api-info oRetry = requests.packages.urllib3.util.retry.Retry (total = 4, status_forcelist = [429, 500, 502, 503, 504], backoff_factor = 1) oAdapter = requests.adapters.HTTPAdapter (max_retries = oRetry) oHttpSession = requests.Session () oHttpSession.mount ("https://", oAdapter) # Get the list from NEOfixer API. s = oHttpSession.get (sURL, timeout = 15).text except: print ('Unable to get target list from NEOfixer.') raise else: # Convert JSON to dictionary. try: d = json.loads (s) dResult = d['result'] except: try: print ('NEOfixer says: ' + d['error']['message']) except: print ('Unable to parse reply from NEOfixer.') else: # Get all the objects returned. dObjects = dResult['objects'] # If only wanted specific targets (-o). if oArgs.objs != None: # See if they are in the NEOfixer reply and keep just them. dTargets = {} for sID, dObj in dObjects.items (): if sID in oArgs.objs: dTargets[sID] = dObj # Else use all targets returned. else: dTargets = dObjects # If no targets passing. if len (dTargets) < 1: print ("\nNo matching targets.", file=sys.stderr) exit (1) # Print table header. print ('\nID Priority Score Cost Mag 1-sigma', file=sys.stderr) print (' (min) (V) (deg)', file=sys.stderr) print ('----------------------------------------------------------', file=sys.stderr) # For each object. for sID, dObj in dTargets.items (): # Get some values we want to output. sPriority = dObj['priority'] fScore = dObj['score'] fCost = dObj['cost'] fMag = dObj['vmag'] fUncert = dObj['uncert'] # Make sure they are defined for display purposes. if sPriority == None: sPriority = '-'; if fScore == None: fScore = -1; if fCost == None: fCost = -1; if fMag == None: fMag = -1; if fUncert == None: fUncert = -1; # Output line for the object. print (f"{dObj['packed']:7s} {sPriority:<12s} {fScore:12.5f} {fCost:7.1f} {fMag:6.1f} {fUncert:8.4f}")