def Recover(self, filename): from file_module import DumpRecover """ Recovering queries from previous job that have been on hold. """ self.query = DumpRecover(filename + "_query") self.attendant = DumpRecover(filename + "_att")
class AstEphem: __version__ = 0.5 from datetime import datetime from dateutil import relativedelta as datedelta from math import pi, degrees, cos global NOW, datedelta, pi, degrees, cos NOW = datetime.utcnow() """ A python new class to manipulate asteroid ephemeris through large data flows. This tools is aimed for finding a great number of asteroids suitable for a large scope of observation goals. The orbital catalogue is provided by the MPC data. """ def __init__(self): from platform import system if system() == "Linux": import subprocess as sp import os fnull = open(os.devnull, "w") if sp.call(["ls", "subroutines.so"], stdout=fnull, stderr=fnull) == 2: sp.call(["f2py", "-c", "-m", "subroutines", "subroutines.f90"], stdout=fnull, stderr=fnull) fnull.close() def LoadMPC(self, **par): """ Input: boolean conditions for sampling. Output: allocate a masked dictionary of orbital parameters from MPC catalogue. """ from os import path from boolean_module import boolist from packdesig import convert_design as conv_desig # Loading the MPC catalogue from gzip compression. if path.isfile(path.join("catalogues", "MPC_ORBITS.gz")): import gzip MPC = gzip.open(path.join("catalogues", "MPC_ORBITS.gz"), "r") else: from urllib2 import urlopen MPC = urlopen("http://www.minorplanetcenter.net/iau/MPCORB/MPCORB.DAT", timeout=30) asteroid = dict() n = 0 for ast in MPC.readlines(): n += 1 if n > 41: try: tested_conditions = boolist( par, H=float(ast[8:12]), G=float(ast[15:19]), a=float(ast[93:103]), e=float(ast[70:79]), i=float(ast[59:68]), ) if all(tested_conditions): asteroid[conv_desig(ast[:7])] = tuple(ast[8:104].split()) except ValueError: try: tested_conditions = boolist(par, a=float(ast[93:103]), e=float(ast[70:79]), i=float(ast[59:68])) if all(tested_conditions): asteroid[conv_desig(ast[:7])] = tuple([0e0, 0.15] + ast[20:104].split()) except ValueError: # print("Null entry in the line ",n," of the MPC catalogue........continue") pass print( "\n MPC catalogue has been read. The total of asteroids fullfilling the conditions are ", len(asteroid), " of ", n - 43, ) # setting in self: self.asteroid = asteroid def Save(self, filename): from file_module import DumpQuery """ Save queries for later in a pickle file. """ DumpQuery(self.query, filename + "_query") DumpQuery(self.attendant, filename + "_att") def Recover(self, filename): from file_module import DumpRecover """ Recovering queries from previous job that have been on hold. """ self.query = DumpRecover(filename + "_query") self.attendant = DumpRecover(filename + "_att") def HowMany(self, key): search = list() app = search.append for ast in self.attendant.iterkeys(): if self.attendant[ast].has_key(str(key)): app(ast) # print(ast,self.attendant[ast]) print("There is ", len(search), " asteroids with ", key) return search def LoadTax(self): from file_methods import LoadTaxCat """ Load PDS data containing asteroid with classification in THOLEN, BUS, BARUCCI or TEDESCO systems. The data set is EAR_A_5_DDR_TAXONOMY_V6_0. """ try: att = self.attendant att = LoadTaxCat(att) except KeyError: print("WARNING: Load Sampling() attribute first.") def SetObserver(self, lat="-8:47:32", lon="-38:41:18", elev=390, hor="10:00:00"): """ Input: site latitude (lat), site longitude (lon), site elevation (elev) and site horizon (hor) Output: Allocate a pyephem class with parameters of the observation site. """ here = ephem.Observer() here.lat, here.lon, here.horizon = str(lat), str(lon), str(hor) here.elev = elev here.temp = 25e0 here.compute_pressure() print("Observer info: \n", here) # setting in self self.here = here def LoadObject(self, des): """ Input: asteroid Designation (des). Output: Return pyephem class with asteroid ephemeris for any date or observer. """ from packdesig import convert_date ast = ephem.EllipticalBody() """ EllipticalBody elements: _inc — Inclination (°) _Om — Longitude of ascending node (°) _om — Argument of perihelion (°) _a — Mean distance from sun (AU) _M — Mean anomaly from the perihelion (°) _epoch_M — Date for measurement _M _size — Angular size (arcseconds at 1 AU) _e — Eccentricity _epoch — Epoch for _inc, _Om, and _om _H, _G — Parameters for the H/G magnitude model _g, _k — Parameters for the g/k magnitude model """ # Reading H, G, epoch_M, M, argper, node, i, e, n, a = self.asteroid[des] # Asteroid Parameters ast._H, ast._G, ast._M, ast._om, ast._Om, ast._inc, ast._e, ast._a = map( float, [H, G, M, argper, node, i, e, a] ) ast._epoch_M = str(convert_date(epoch_M)) # Constants ast._epoch = str("2000/1/1 12:00:00") return ast def Sampling(self, datestart=None, datestop=None, typetime="hour", parse=2, **limits): """ This method conducts a query through ephemeris of MPC asteroid catalogue sampling objects within a date range and phase angle interval. """ from module import vmag, phase_angle, SeqDates, float_ra from boolean_methods import boolist degrees = ephem.degrees here = self.here # dates if datestart is None and datestop is None: datestart = NOW datestop = NOW + datedelta.relativedelta(days=+1) # range of dates. dates = SeqDates(datestart, datestop, typetime, parse) # designations designation = dict.viewkeys(self.asteroid) obj_ephem = {ast: self.LoadObject(ast) for ast in designation} query = dict() # Dictionary attendant = dict() for date in dates: date = str(date) query[date] = dict() # Dictionary inside Dictionary here.date = date for ast in designation: obj = obj_ephem[ast] obj.compute(here) # Ephemeris for the date angle = phase_angle(obj.elong, obj.earth_distance, obj.sun_distance, here) mag = vmag(obj._H, obj._G, angle, obj.sun_distance, obj.earth_distance) airmass = round(1e0 / cos(pi / 4e0 - float(obj.alt)), 4) tested_conditions = boolist( limits, ph=angle, r=obj.sun_distance, mag=mag, alt=degrees(float(obj.alt)), airmass=airmass, az=degrees(float(obj.az)), ra=float_ra(obj.a_ra), dec=degrees(float(obj.a_dec)), ) if all(tested_conditions) and obj.alt >= here.horizon: query[date][ast] = { "phase angle": round(angle, 3), "vmag": round(mag, 3), "solar distance": obj.sun_distance, "ra": str(obj.a_ra), "dec": str(obj.a_dec), "alt": str(obj.alt), "airmass": airmass, "az": str(obj.az), } # Dictionary inside Dictionary inside Dictionary if attendant.has_key(ast) == False: attendant[ast] = {"dates": list()} attendant[ast]["dates"].append(date) # setting in self self.attendant = attendant self.query = query print("There are ", len(dict.viewkeys(attendant)), " asteroids satisfying this query.") def SamplingTax(self, *symbols): from boolean_module import taxboolist """ Selects the asteroid ephemeris by its taxonomic classification. """ conditions = taxboolist(symbols) if len(self.HowMany("taxclass")) == 0: self.LoadTax() att = self.attendant taxquery = dict() for ast in dict.keys(att): if att[ast].has_key("taxclass"): tested_conditions = any([test(att[ast]["taxclass"]) for test in conditions]) if tested_conditions: taxquery[ast] = tuple(att[ast]["taxclass"]) print("Asteroids belonging to the inquired classifications are ", len(taxquery)) return taxquery ###################### Unfinished ############################################## def ExpositionTime(self, SNR, N, De, L, T, b, dark, readout, pixel_size): import module from subroutines import exptime """ Input: SNR --> Signal-to-Noise ratio N --> Number of pixel in the aperture De --> Effective diameter of the telescope L --> Effective focal length T --> Optical Transmission Efficiency b --> Angular size of the source in radians wv --> Central wavelength of the bandpass in cm delta_wv --> Bandwidth of the filter in cm. F0 --> flux zeropoint for a given filter. dark --> Dark current rate per pixels readout --> Readout Noise rate per pixel Constants: h --> planck constant c --> speed of light m_back --> Sky surface brightness at night pixel_size --> pixel size in cm Filter: wv --> Central wavelength of the bandpass in cm delta_wv --> Bandwidth of the filter in cm. F0 --> flux zeropoint for a given filter. Output: t --> Exposition Time """ query = self.query for date in dict.iterkeys(query): for ast in dict.iterkeys(query[date]): mag = query[date][ast]["vmag"] query[date][ast]["exptime"] = exptime(mag, SNR, N, De, L, T, b, dark, readout)