Ejemplo n.º 1
0
    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")
Ejemplo n.º 2
0
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)