Ejemplo n.º 1
0
def non_sidereal_ra(target_name):
    global eph_obj_coords

    if eph_obj_coords is None:
        try:
            # if there is a space in the nane, assume the first string is an acceptable name
            obj = Horizons(id=target_name[0].split()[0], epochs=Time.now().jd)
            eph_obj_coords = [
                obj.ephemerides()['RA'][0],
                obj.ephemerides()['DEC'][0]
            ]
            return eph_obj_coords[0]
        except:
            pass
    return None
Ejemplo n.º 2
0
Archivo: test.py Proyecto: AngusMcM/shp
def horizons(location, target, cat):
    Rarray = np.empty(1)
    Decarray = np.empty(1)
    for i in range(0, len(cat), 350):
        print 'loop ' + str(i)
        epoch = cat[i:i + 350]
        print len(epoch)
        epochs = []
        for j in range(0, len(epoch)):
            epochs.append(epoch[j][1])
        print epochs
        epochs = np.array(epochs)
        obj = Horizons(id=target,
                       location=location,
                       id_type='majorbody',
                       epochs=epochs)
        eph = obj.ephemerides()
        newRA = np.array(eph['RA'])
        print eph['targetname']
        newDec = np.array(eph['DEC'])
        Rarray = np.concatenate((Rarray, newRA))
        Decarray = np.concatenate((Decarray, newDec))
    for i in range(0, len(cat)):
        cat[i][5] = Rarray[i + 1]
        cat[i][6] = Decarray[i + 1]
    return cat
Ejemplo n.º 3
0
def get_earth_ephemerides(epoch_start, epoch_stop, step_size, type_elements):

    # step: step size, [10m, 1d, 1y]

    obj = Horizons(id='Geocenter',
                   location='500@10',
                   epochs={
                       'start': epoch_start,
                       'stop': epoch_stop,
                       'step': step_size
                   },
                   id_type='majorbody')

    if type_elements.lower() == 'vectors':
        data_output = obj.vectors()  # vectorial elements
    elif type_elements.lower() == 'ephemerides':
        data_output = obj.ephemerides()

    len_rows = len(data_output)
    len_cols = 6  # 3 positions 'x','y','z', and 3 velocities 'vx', 'vy', 'vz'
    idx_x = 3  # 'x' is at position 3 in the table
    data = np.zeros([len_rows, len_cols])
    for row in range(len_rows):
        for col in range(6):
            idx_col_in_table = idx_x + col  # because the 'x' start at 3rd col, going up till the 9th that is 'vz'
            data[row, col] = data_output[row][idx_col_in_table]

    return data
Ejemplo n.º 4
0
def get_ephemeris(args):
    epochs = dict(start=args.start_date.iso,
                  stop=args.stop_date.iso,
                  step=args.step)
    id_type = args.type

    # ephemeris options
    opts = dict(solar_elongation=(85, 135), cache=(not args.no_cache))

    # comets need special care: use closest orbital elements by date, do not
    # search for related fragments
    if args.type == 'comet':
        id_type = 'designation'
        opts.update(closest_apparition=True, no_fragments=True)

    horizons = Horizons(args.target,
                        location='@jwst',
                        epochs=epochs,
                        id_type=id_type)
    eph = horizons.ephemerides(**opts)
    eph['date'] = Time(eph['datetime_jd'], format='jd')

    if len(eph) == 0:
        print('''No epochs observable by JWST.
    Try a new date range and/or finer time steps.''')
        sys.exit(1)

    return eph
Ejemplo n.º 5
0
def get_target_ephemeris(desg, start_date, end_date, smallbody=False):
    """Ephemeris from JPL/HORIZONS.
    smallbody : bool, optional
      Set to `True` for comets and asteroids, `False` for planets,
      spacecraft, or moons.
    Returns : target name from HORIZONS, RA, and Dec.
    """

    if smallbody:
        bodytype = 'smallbody'
    else:
        bodytype = 'majorbody'

    obj = Horizons(id=desg,
                   location='500@-170',
                   id_type=bodytype,
                   epochs={
                       'start': start_date,
                       'stop': end_date,
                       'step': '1d'
                   })

    eph = obj.ephemerides(cache=False, quantities=(1))

    return eph['targetname'][0], eph['RA'], eph['DEC']
Ejemplo n.º 6
0
def photod_rate(time, time_scale, target, id_type, observatory, time_format,
                mol_tag):
    # imported here to avoid circular dependency with activity.gas
    from ..activity.gas import photo_timescale

    epoch = Time(time, scale=time_scale, format=time_format)
    obj = Horizons(id=target, epochs=epoch.jd, location=observatory,
                   id_type=id_type)

    try:
        orb = obj.ephemerides()

    except ValueError:

        raise

    delta = (orb['delta'].data * u.au).to('m')
    r = (orb['r'].data)
    cat = JPLSpec.get_species_table()
    mol = cat[cat['TAG'] == mol_tag]
    name = mol['NAME'].data[0]

    timescale = photo_timescale(name)

    if timescale.ndim != 0:
        # array
        timescale = timescale[0]

    beta = (timescale) * r**2

    return beta, delta
Ejemplo n.º 7
0
    def _get_object_RADEC_from_horizons(self,
                                        object_name,
                                        obs_code,
                                        times,
                                        object_type='smallbody'):
        '''
        Query horizons for the RA & DEC of a
        *known object* at a sequence of times.
        input:
        object_name - string
        obs_code    - string
                    - Note that Horizons uses some weird ones sometimes,
                      like "500@-95" for Tess.
        times       - array of times (JD)
        object_type - string
                    - Usually the default "smallbody" is fine, 
                      but for some objects, like natsats, it's neccessary.

        '''
        horizons_query = Horizons(id=object_name,
                                  location=obs_code,
                                  epochs=times,
                                  id_type=object_type)
        horizons_ephem = horizons_query.ephemerides(extra_precision=False)
        self.RA, self.Dec = np.array(
            [horizons_ephem['RA'], horizons_ephem['DEC']])
    def get_target_xyz(t):
        """
        Returns the vectors of the Horizons body at a certain time t.
        
        Arguments:
        
        t: days
        
        Julian date of observation
        
        Returns:
    
        xyz: numpy array
        
        A position vector of the observed object
    
        uvw: numpy array
        
        An instantaneous velocity vector of the observed object
        """

        obj = Horizons(id=name, location=loc, epochs=t, id_type='majorbody')
        obj1 = obj.vectors(aberrations=cor, refplane='earth')
        xyz = np.array([float(obj1['x']), float(obj1['y']), float(obj1['z'])])
        uvw = np.array(
            [float(obj1['vx']),
             float(obj1['vy']),
             float(obj1['vz'])])
        obj2 = obj.ephemerides(refsystem='J2000', extra_precision=True)
        radec = np.array(
            [float(obj2['RA']),
             float(obj2['DEC']),
             float(obj1['range'])])
        return xyz, uvw, radec
Ejemplo n.º 9
0
def get_planet_timelines(planet_id, start_date, end_date,
						time_step):

    #planet_id can be either a 3digit number from the IAU
    #catalogue either the barycenter of the planet
    #insert date in form YYYYMMDD
    filefolder ='//Users/nadia/Downloads/'

    #convert the dates into the correct form YYYY-MM-DD
    start_date = str(start_date)[:4]+'-'+str(start_date)[4:6]+'-'+str(start_date)[6:]
    end_date = str(end_date)[:4]+'-'+str(end_date)[4:6]+'-'+str(end_date)[6:]
    time_step = str(time_step)+'d'

    Epochs = {'start':start_date,'stop':end_date,
    'step':time_step}

    obj = Horizons(id = str(planet_id), id_type = 'majorbody',
    location = None, epochs = Epochs)

    eph = obj.ephemerides()
    ra = np.array(eph['RA'])
    dec = np.array(eph['DEC'])
    t = np.array(eph['datetime_jd'])
    timelines = {'t':t, 'ra':ra, 'dec':dec}

    np.save(opj(filefolder, 'Planet_'+str(planet_id)+'_timelines'), timelines)
    return(ra,dec)
def get_planetary_positions(target,type='majorbody'):
    '''
    Gets ephemerides data (planetary positions) using JPL Horizons program for given planet at predefined times
    '''
    planet_pos_data = Horizons(id=target, id_type=type, location=LOCATION, epochs=EPOCHS)
    eph = planet_pos_data.ephemerides()
    eph['r'].convert_unit_to('km')
    return eph['targetname','datetime_str','EclLon','EclLat','r']
Ejemplo n.º 11
0
    def download_ephemeris_data(self, body, dates, coordinates):
        """Downloads ephemeris data by querying the JPL Horizons site"""
        bodies_class = Bodies(*self.get_body_list())
        bodykey = bodies_class.get_body_code(body)
        uncertainties = []
        downloaded_data = []
        log_file = "Log.txt"
        for i in tqdm(range(0, len(dates), 380)):
            jpl_horizon = Horizons(id=bodykey,
                                   location=coordinates,
                                   epochs=dates[i:i + 380],
                                   id_type='id')
            eph = jpl_horizon.ephemerides(quantities='1,9,36',
                                          get_raw_response=True,
                                          refsystem='B1950',
                                          refraction=True).split("\n")

            for i in range(0, len(eph)):
                if "$$SOE" in eph[i]:
                    lower_bound = i
                if "$$EOE" in eph[i]:
                    upper_bound = i
                    data_points = eph[lower_bound + 1:upper_bound]
                    break
            try:
                for i in range(0, len(data_points)):
                    if len(data_points[i]) == 10:
                        uncertainties = [
                            data.strip()
                            for data in data_points[i].split(",")[8:10]
                        ]
                    else:
                        uncertainties = [
                            data.strip()
                            for data in data_points[i].split(",")[7:9]
                        ]
                    data_points[i] = [
                        data.strip() for data in data_points[i].split(",")[4:7]
                    ]
                    data_points[i] += uncertainties
                    downloaded_data.append(" ".join(data_points[i]))
            except UnboundLocalError:
                with open(os.path.join(self.temp_files,
                                       log_file)) as error_logger:
                    for line in eph:
                        logging.write("{}\n".format(line))
                    raise Exception(
                        "Problem With Loading Ephemeris Data, Check Log.txt File For More Details"
                    )

        with open(os.path.join(self.temp_files, log_file), "w") as logging:
            print("Writing Ephemeris Log")
            for line in eph:
                logging.write("{}\n".format(line))

        self.cache_ephemeris_data(body, downloaded_data)

        return downloaded_data
Ejemplo n.º 12
0
def getHorizonsEphemeris(
        obj_ids, 
        observers, 
        id_type="smallbody"
    ):
    """
    Query JPL Horizons (through astroquery) for an object's
    ephemerides at the given times viewed from the given location.
    
    Parameters
    ----------
    obj_ids : `~numpy.ndarray` (N)
        Object IDs / designations recognizable by HORIZONS. 
    observers : dict or `~pandas.DataFrame`
        A dictionary with observatory/location codes as keys and observation_times (`~astropy.time.core.Time`) as values. 
        Location of the observer which can be an MPC observatory code (eg, 'I41', 'I11')
        or a NAIF code ('0' for solar system barycenter, '10' for heliocenter)
    id_type : {'majorbody', 'smallbody', 'designation', 
               'name', 'asteroid_name', 'comet_name', 'id'}
        ID type, Horizons will find closest match under any given type.
    
    Returns
    -------
    ephemeris : `~pandas.DataFrame`
        Dataframe containing the RA, DEC, r, r_rate, delta, delta_rate and light time 
        of the object at each time. 
    """
    dfs = []
    for orbit_id, obj_id in enumerate(obj_ids):
        for observatory_code, observation_times in observers.items():
            _checkTime(observation_times, "observation_times")
            obj = Horizons(
                id=obj_id, 
                epochs=observation_times.utc.mjd, 
                location=observatory_code,
                id_type=id_type
            )
            ephemeris = obj.ephemerides(
                # RA, DEC, r, r_rate, delta, delta_rate, lighttime
                #quantities="1, 2, 19, 20, 21",
                extra_precision=True
            ).to_pandas()
            ephemeris["orbit_id"] = [orbit_id for i in range(len(ephemeris))]
            ephemeris["observatory_code"] = [observatory_code for i in range(len(ephemeris))]
            ephemeris["mjd_utc"] = observation_times.utc.mjd

            dfs.append(ephemeris)

    ephemeris = pd.concat(dfs)
    ephemeris.sort_values(
        by=["orbit_id", "observatory_code", "datetime_jd"],
        inplace=True
    )
    ephemeris.reset_index(
        inplace=True,
        drop=True
    )
    return ephemeris
def obj_query(identifier, 
              location, 
              start_date, 
              stop_date, 
              step_size, 
              min_mag,
              ):
    """ Responsible for pulling ephemeris information from JPL Horizons"""

    # Calls object identified with date information from JPL horizons.    
    obj = Horizons(id=identifier, location=location,
                   epochs={'start':start_date,
                           'stop':stop_date,
                           'step':step_size},                     
                   )

    # Checks if Daylight needs to be skipped
    if skip_day == 'y':
        # Creating Ephemeris without daylight hours
        eph = obj.ephemerides(skip_daylight=True)
    else:
        # Creating ephemeris object at all hours
        eph = obj.ephemerides(skip_daylight=False)  
    
     
    # Convert table to pandas dataframe (easier to manipulate).
    eph_df = eph[column_names].to_pandas()
    
    # Removes objects with airmass higher then limit
    if airmass_q == True:
        eph = airmass_limit(eph_df, airmass_lim)
    
    # Check if Plots need to be saved before editing dataframe.
    if save_plot[0].lower() == 'y':
        plotter(eph_df, identifier, min_mag)
    else:
        pass
        
    # Uses find oppositions to find opposition dates.
    min_eph_df = find_oppositions(min_mag, eph_df)

    return min_eph_df
Ejemplo n.º 14
0
def Anal(filenames,Plot,Target,Aperture,SS):

    Res = []
    JD = []
    Alpha = []
    PlAng = []
    All = []
    retarder =[]
    Stoke_Final = []
    for elem in filenames:
        stokes = []
        with open(elem,'r') as f:
            for elem in f.readlines():
                print(elem)
                stokes.append(float(elem.replace('\n',' ').replace('\t',' ').split()[2]))
            
        Stoke_Final.append(stokes)
        JD.append(float(elem.replace('\n',' ').replace('\t',' ').split()[0]))
        retarder.append(float(elem.replace('\n',' ').replace('\t',' ').split()[1]))
        
        if not SS:
            obj = Horizons(id=Target, location='679', epochs=float(elem.replace('\n',' ').replace('\t',' ').split()[0]))
            eph = obj.ephemerides()
            Alpha.append(eph['alpha'][0])
            PlAng.append(eph['sunTargetPA'][0])  
        All.append(stokes)
        if Plot:    
            plt.plot(stokes)
            
            
#        Res.append(np.median(stokes[Aperture]))  


    All = np.array(All)
    print(np.sqrt((1./2*(All[0,:]-All[2,:]))**2+(1./2*(All[1,:]+All[3,:]))**2))
    plt.plot(np.sqrt((1./2*(All[0,:]-All[2,:]))**2+(1./2*(All[1,:]-All[3,:]))**2),Linewidth = 3)
    
    plt.show() 

    if not Aperture:
        Aperture = int(raw_input("What aperture to you want to use? "))

    print()
  
    Res = All[:,Aperture]
    
    if not SS:
        with open('result.txt', 'w') as f:
            for idx,elem in enumerate(Res):
                f.write(str(retarder[idx]) + '\t' + str(JD[idx]) + '\t' + str(Alpha[idx]) + '\t' + str(PlAng[idx]) + '\t' + str(elem) + '\n')
    else:
        with open('result_Standard.txt', 'w') as f:
            for idx,elem in enumerate(Res):
                f.write(str(retarder[idx]) + '\t' + str(JD[idx]) + '\t' + str(0) + '\t' + str(0) + '\t' + str(elem) + '\n')
Ejemplo n.º 15
0
    def get_sso_ephem(self, name, epoch_start, epoch_end, epoch_step="1min", location="A84"):
        """Instantiate JPL query.

        Parameters
        ----------
        name : str, required
            Name, number, or designation of the object to be queried
        location : str or dict, optional
            Observer's location for ephemerides queries or center body
            name for orbital element or vector queries. Uses the same
            codes as JPL Horizons. If no location is provided, Earth's
            center is used for ephemerides queries and the Sun's
            center for elements and vectors queries. Arbitrary topocentic
            coordinates for ephemerides queries can be provided in the
            format of a dictionary. The
            dictionary has to be of the form {``'lon'``: longitude in
            deg (East positive, West negative), ``'lat'``: latitude in
            deg (North positive, South negative), ``'elevation'``:
            elevation in km above the reference ellipsoid, [``'body'``:
            Horizons body ID of the central body; optional; if this value
            is not provided it is assumed that this location is on Earth]}.
        epochs : scalar, list-like, or dictionary, optional
            Either a list of epochs in JD or MJD format or a dictionary
            defining a range of times and dates; the range dictionary has to
            be of the form {``'start'``:'YYYY-MM-DD [HH:MM:SS]',
            ``'stop'``:'YYYY-MM-DD [HH:MM:SS]', ``'step'``:'n[y|d|m|s]'}.
            Epoch timescales depend on the type of query performed: UTC for
            ephemerides queries, TDB for element queries, CT for vector queries.
            If no epochs are provided, the current time is used.
        id_type : str, optional
            Identifier type, options:
            ``'smallbody'``, ``'majorbody'`` (planets but also
            anything that is not a small body), ``'designation'``,
            ``'name'``, ``'asteroid_name'``, ``'comet_name'``,
            ``'id'`` (Horizons id number), or ``'smallbody'`` (find the
            closest match under any id_type), default: ``'smallbody'``


        Examples
        --------
            >>> from astroquery.jplhorizons import Horizons
            >>> eros = Horizons(id='433', location='568',
            ...              epochs={'start':'2017-01-01',
            ...                      'stop':'2017-02-01',
            ...                      'step':'1d'})
            >>> print(eros)  # doctest: +SKIP
            JPLHorizons instance "433"; location=568, epochs={'start': '2017-01-01', 'step': '1d', 'stop': '2017-02-01'}, id_type=smallbody
        """

        obj = Horizons(id=name, location=location,
                       epochs={'start': '{}'.format(epoch_start), 'stop': '{}'.format(epoch_end),
                               'step': '{}'.format(epoch_step)})
        eph = obj.ephemerides()
        return eph
Ejemplo n.º 16
0
def targetEphemerisFromHorizons(target_id,
                                observer_location,
                                tstart,
                                tstop,
                                ephemeris_dt='12h'):
    """Query JPL Horizons via astroquery to get sun-observer state vectors.
    
    Parameters:
    -----------
    target_id          ... Horizons identifyer target, e.g. 'Ceres'
    observer_location  ... Horizons identifyer of observer location, e.g. 'I11'
    tstart             ... start time for ephemeris in Horizons format, e.g. 'JD2456789.5'
    tstop              ... end time for ephemeris in Horizons format, e.g. 'JD2456799.5'
    ephemeris_dt       ... Time step for ephemeris query. 
                           Typically 1h since the actual times will be interpolated later.
    
    Returns:
    --------
    RA, DEC               ... Right Ascension and Declination of target wrt observer
    ephemeris_jd        ... Ephemeris epochs (JD / UTC)
    
    External Function Requirements:
    -------------------------------
    # External API's
    from astroquery.jplhorizons import Horizons
    """
    try:
        # Get observer locations (caution: choose the right plane of reference and direction of the vectors!)
        # check query by copy/pasting the output of print(observer_sun.uri) into a webbrowser if there are problems.

        #         tmin = 'JD'+str(tstart)
        #         tmax = 'JD'+str(tstop+1.)

        tmin = tstart
        tmax = tstop
        observer2target = Horizons(id=target_id,
                                   location=observer_location,
                                   epochs={
                                       'start': tmin,
                                       'stop': tmax,
                                       'step': ephemeris_dt
                                   })

        ra, dec = observer2target.ephemerides()['RA', 'DEC']
        jd = (observer2target.vectors())['datetime_jd']

    except:
        print(
            "Error in observer_state_from_horizons: potential online ephemeris query failure."
        )
        raise

    return ephemeris_jd, ra, dec
Ejemplo n.º 17
0
def get_radec_fromjpl(ssid='',location='511',jd=2454545.0):
    """Get Solar System Object position from Horizons
    
    Parameters
    ----------
    ssid : string, optional
        JPL id of the object to be found.
        Default is empty string.
    location : string, optional
        IAU observatory code. Default is '511' (OHP).
    jd : float, optional
        Juliand day for the computation of the ephemeris.
        Default is J2000.
    
    Returns
    -------
    skycoo : astropy.coordinates.Skycoordinate Object
        Sky coordinates (RA,DEC) of the object.
    
    """
    defhorserver()
    sshor = Horizons(id=ssid,location=location,epochs=jd)
    try:
        eph = sshor.ephemerides()
    except Exception as e:
        if ('Ambiguous' in str(e)):
            ssidjpl = str(e).split('\n')[-2].split()[0]
            t120.log.warning('Ambiguous name detected! Corrected to id='+ssidjpl)
            try:
                sshor = Horizons(id=ssidjpl,location=location,epochs=jd)
                eph = sshor.ephemerides()
            except Exception as e:
                raise(e)
        else:
            raise(e)
    skycoo = SkyCoord(eph['RA'][0],eph['DEC'][0],unit='deg',obstime=Time(jd,format='jd'))
    t120.log.info(ssid+' '+skycoo.to_string(style='hmsdms'))
    return skycoo
Ejemplo n.º 18
0
def get_path(obj_name, times, id_type='smallbody', location=None):
    """

    # See more details at https://astroquery.readthedocs.io/en/latest/jplhorizons/jplhorizons.html
    # For valid locations: https://minorplanetcenter.net//iau/lists/ObsCodesF.html

    Parameters
    ----------

    obj_name: str
       Object name. May require specific formatting (i.e. selecting between
       the codes for Jupiter and Jupiter barycenter). See JPL Horizons documentation

    times: float or arr
       Times to check, input as a float, array, or specified start/stop/step
       (example: {'start':'2019-01-01', 'stop':'2019-12-31', 'step':'1d'})

    id_type: str
       Object ID type for JPL Horizons. Defaults to smallbody (an asteroid or comet).
       Best to be as specific as possible to find the correct body.

       majorbody: planets and satellites
       smallbody: asteroids and comets
       asteroid_name: name of asteroid
       comet_name: name of comet
       name: any target name
       designation: any asteroid or comet designation

    location: str
       Default of None uses a geocentric location for queries.
       For specific spacecrafts, insert location

       Examples:
       TESS: @TESS
       Hubble: @hst
       Kepler: 500@-227

    Returns
    -------
    eph: Astropy table
        Table object with the JPL Horizons calculated ephemerides

    """

    obj = Horizons(id=obj_name,
                   location=location,
                   id_type=id_type,
                   epochs=times)
    eph = obj.ephemerides()
    return eph
def dl_flats(xtag, idx, locationx, epochsx, quantitiesx):
    '''
    Standard set-up for downloading flatfiles. Minimal preprocessing.
    '''
    obj = Horizons(id=idx, location=locationx, epochs=epochsx,
                   id_type='majorbody')
    # Precision increases only for the RA DEC only, not the angles
    eph = obj.ephemerides(quantities=quantitiesx, extra_precision=True)
    dropthese = ['targetname']
    del eph[dropthese]
    oldcol = list(eph.columns)
    oldcol = [s for s in oldcol if not s.startswith('datetime')]
    newcol = [xtag + '_' + s for s in oldcol]
    eph.rename_columns(oldcol, newcol)
    return eph
Ejemplo n.º 20
0
    def query(self, depoch=100, *args, **kwargs):
        '''
        Parameters
        ----------
        depoch : int, optional
            The number of discrete epochs to be chopped.

        args, kwargs : optional.
            Passed to ``.ephemerides()`` of ``Horizons``.
        '''
        Nepoch = np.shape(self.epochs)[0]
        Nquery = (Nepoch - 1) // depoch + 1
        tabs = []

        print(f'Query: {self.targetname} ' +
              f'at {self.location} for {Nepoch} epochs'
              '')

        if Nquery > 1:
            print(f"Query chopped into {Nquery} chunks: Doing ", end=' ')

        for i in range(Nquery):
            print(f"{i+1}...", end=' ')
            i_0 = i * depoch
            i_1 = (i + 1) * depoch
            epochs_i = self.epochs[i_0:i_1]

            obj = Horizons(
                id=self.targetname,  #
                location=self.location,  #
                epochs=epochs_i,  #
                id_type=self.id_type)
            eph = obj.ephemerides(*args, **kwargs)

            tabs.append(eph)
            self.uri.append(obj.uri)

        if len(tabs) == 1:
            self.query_table = tabs[0]

        elif len(tabs) > 1:
            self.query_table = vstack(tabs)

        print("Query done.")

        return self.query_table
Ejemplo n.º 21
0
def check_detectability(obj_id="2020 DA4",
                        obs_lat=69.3908,
                        obs_lon=20.2673,
                        obs_el=0.0,
                        start="2020-01-01",
                        stop="2020-06-01",
                        step="2h",
                        min_el=30.0,
                        id_type="smallbody",
                        debug=False):

    e3d = {'lon': obs_lon, 'lat': obs_lat, 'elevation': obs_el}
    obj = Horizons(id=obj_id,
                   location=e3d,
                   epochs={
                       "start": start,
                       "stop": stop,
                       "step": step
                   },
                   id_type=id_type)

    #    t0=obj.ephemerides(quantities="4,20",get_raw_response=True)

    t = obj.ephemerides(quantities="4,20", get_raw_response=False)
    if debug:
        print(t)
    els = []
    ranges = []
    range_rates = []
    dates = []
    for r in t:

        name = r[0]
        date = r[1]
        az = r[7]  # deg
        el = r[8]  # deg

        if el > min_el:
            delta = r[9] * c.au  # m
            delta_rate = r[10] * 1e3  #m/s
            #            print("el %1.2f range %1.2g range-rate %1.2f gain %1.2f"%(el,delta,delta_rate/1e3,g_dB))
            els.append(float(el))
            ranges.append(delta)
            range_rates.append(delta_rate)
            dates.append(r[1])
    return (n.array(ranges), n.array(range_rates), n.array(els), dates)
Ejemplo n.º 22
0
def test_Ephemerides_Vectors_Astrometric():
    strstartdate = '2021-1-1 12:00:00'
    strenddate = '2021-1-2 12:00:00'
    start_time = Time(strstartdate)
    start_time_tdb = start_time.tdb
    end_time = Time(strenddate)
    end_time_tdb = end_time.tdb
    # print(start_time.value, start_time_tdb.value)
    mars_by_earth_obs = Horizons(id='499',
                                 id_type='majorbody',
                                 location='500',
                                 epochs={
                                     'start': start_time.value,
                                     'stop': end_time.value,
                                     'step': '1'
                                 })
    mars_by_earth_vec = Horizons(id='499',
                                 id_type='majorbody',
                                 location='500',
                                 epochs={
                                     'start': start_time_tdb.value,
                                     'stop': end_time_tdb.value,
                                     'step': '1'
                                 })
    mars_by_earth_obs_data = mars_by_earth_obs.ephemerides(
        quantities='1,2,4,20,31')
    mars_by_earth_vec_astrometric = mars_by_earth_vec.vectors(
        refplane='earth', aberrations='astrometric', delta_T=True)
    mars_by_earth_vec_apparent = mars_by_earth_vec.vectors(
        refplane='earth', aberrations='apparent', delta_T=True)
    mars_by_earth_vec_geometric = mars_by_earth_vec.vectors(refplane='earth',
                                                            delta_T=True)
    print(
        "比較 Horizons 中,用 Observer 模式查得的 RA/DEC與用Vectors模式(aberrations='astrometric')查得的是否相同?是相同!"
    )
    print(mars_by_earth_obs_data['datetime_str', 'RA', 'DEC', 'RA_app',
                                 'DEC_app', 'delta'])
    # print(mars_by_earth_vec_astrometric['x','y','z','lighttime'])
    astrometric_position = SkyCoord(
        x=mars_by_earth_vec_astrometric['x'].tolist() * u.au,
        y=mars_by_earth_vec_astrometric['y'].tolist() * u.au,
        z=mars_by_earth_vec_astrometric['z'].tolist() * u.au,
        representation_type='cartesian',
        frame='gcrs')
    astrometric_position.representation_type = 'spherical'
    print(astrometric_position)
Ejemplo n.º 23
0
def horizons(location, target, cat, id_type):
    extra = np.zeros((len(cat)))
    extra2 = np.zeros((len(cat)))
    extra3 = np.zeros((len(cat)))
    cat = np.column_stack((cat, extra, extra2, extra3))
    Rarray = np.empty(1)
    Decarray = np.empty(1)
    galbarray = np.empty(1)
    gallarray = np.empty(1)
    magarray = np.empty(1)
    for i in range(0, len(cat), 350):
        progress = round((i * 100 / float(len(cat))), 1)
        print str(progress) + '%'
        epoch = cat[i:i + 350]
        epochs = []
        for j in range(0, len(epoch)):
            epochs.append(epoch[j][1])
        epochs = np.array(epochs)
        obj = Horizons(id=target,
                       location=location,
                       id_type=id_type,
                       epochs=epochs)
        eph = obj.ephemerides()
        if i == 0:
            targetname = eph['targetname'][i]
        newRA = np.array(eph['RA'])
        newDec = np.array(eph['DEC'])
        newgalb = np.array(eph['GlxLat'])
        newgall = np.array(eph['GlxLon'])
        newMag = np.array(eph['V'])
        Rarray = np.concatenate((Rarray, newRA))
        Decarray = np.concatenate((Decarray, newDec))
        galbarray = np.concatenate((galbarray, newgalb))
        gallarray = np.concatenate((gallarray, newgall))
        magarray = np.concatenate((magarray, newMag))
    for i in range(0, len(cat)):
        cat[i][5] = Rarray[i + 1]
        cat[i][6] = Decarray[i + 1]
        cat[i][8] = gallarray[i + 1]
        cat[i][9] = galbarray[i + 1]
        cat[i][10] = magarray[i + 1]
    cat[:, 5] = np.radians(cat[:, 5])
    cat[:, 6] = np.radians(cat[:, 6])
    targetname = targetname.replace(' ', '_')
    return cat, targetname
Ejemplo n.º 24
0
def getRadec(obsid,horizon_id,coord,aster):
    # coord: '@swift' or 500
    img_name = 'sw'+str(obsid)+'ugu_sk.img.gz'
    #img_name = 'sw'+obsid+'uw2_sk.img'
    img_path = '/Users/zexixing/Research/swiftASTER/data/'+aster+'/'+\
               obsid+'/uvot/image/'+img_name
    hdul = fits.open(img_path)
    start = Time(hdul[0].header['DATE-OBS'])
    end = Time(hdul[0].header['DATE-END'])
    dt = end-start
    mid_time = start + 1/2*dt
    obj = Horizons(id=horizon_id,
                   location=coord,
                   epochs=mid_time.jd)
    eph = obj.ephemerides()[0]
    ra = eph['RA']
    dec = eph['DEC']
    return ra, dec
Ejemplo n.º 25
0
    def _query_jpl_horizons(self) -> None:
        """Takes the object name from the text box, queries JPL Horizons, and fills the RA/Dec inputs with the result."""
        from astroquery.jplhorizons import Horizons

        # clear solar system and simbad
        self.comboSolarSystemBody.setCurrentText("")
        self.textSimbadName.clear()

        # wait cursor
        QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)

        # query
        try:
            # query
            obj = Horizons(id=self.textJplHorizonsName.text(),
                           location=None,
                           epochs=Time.now().jd)

            # get ephemerides
            eph = obj.ephemerides()

        except InvalidQueryError:
            QtWidgets.QMessageBox.critical(self, "JPL Horizons",
                                           "No result found")
            return
        except ValueError:
            QtWidgets.QMessageBox.critical(self, "JPL Horizons",
                                           "Invalid result")
            return
        finally:
            # restore cursor
            QtWidgets.QApplication.restoreOverrideCursor()

        # always use first result
        coord = SkyCoord(eph["RA"][0] * u.deg,
                         eph["DEC"][0] * u.deg,
                         frame="icrs")
        self.textMoveRA.setText(coord.ra.to_string(unit=u.hour, sep=" "))
        self.textMoveDec.setText(coord.dec.to_string(sep=" "))

        # update destination
        self._calc_dest_equatorial(clear=False)
Ejemplo n.º 26
0
def mag2afr(horizon_id, mag_v, mag_v_err, aperture, obs_log_name, phase_name,
            phase_corr):
    #def mag2afr(horizon_id, mag_v, mag_v_err, aperture, r, delta, phase, phase_name, phase_corr):

    obs_log_path = get_path('../docs/' + obs_log_name)
    obs_log = pd.read_csv(obs_log_path, sep=' ', index_col=['FILTER'])
    obs_log = obs_log[['HELIO', 'HELIO_V', 'START', 'END', 'OBS_DIS']]
    obs_log = obs_log.loc['V']
    if obs_log.index.name == 'FILTER':
        start = obs_log['START'].iloc[0]
        end = obs_log['END'].iloc[-1]
    else:
        start = obs_log['START']
        end = obs_log['END']
    dt = Time(end) - Time(start)
    mid_time = Time(start) + 1 / 2 * dt
    obj = Horizons(id=horizon_id, location='@swift', epochs=mid_time.jd)
    eph = obj.ephemerides()[0]
    r = eph['r']
    delta = eph['delta']
    phase = eph['alpha']

    # afr
    mag_sun = -26.75
    rou = au2km(as2au(aperture, delta)) * 1000
    factor = np.power(2 * au2km(delta) * r * 1000, 2) / rou
    afr = np.power(10, 0.4 * (mag_sun - mag_v)) * factor
    afr_err = 0.4 * np.log(10) * np.power(
        10, 0.4 * (mag_sun - mag_v)) * mag_v_err * factor
    # phase effect correction
    phase_path = get_path('../docs/' + phase_name)
    phase_file = np.loadtxt(phase_path)
    deg = phase_file[:, 0]
    corr_coef = phase_file[:, 1]
    pha_corr = interpolate.interp1d(deg, corr_coef, fill_value='extrapolate')
    corr_coef = pha_corr(phase)
    if phase_corr == True:
        afr = afr / corr_coef
        afr_err = afr_err / corr_coef
    else:
        pass
    return afr, afr_err
Ejemplo n.º 27
0
def query_ephemerides(cfg):
    #create observer location
    gs = {
        'lon': cfg['gs']['longitude'],
        'lat': cfg['gs']['latitude'],
        'elevation': cfg['gs']['altitude_m'] / 1000.0
    }
    #create query object
    if 'id' in cfg['horizons'].keys(): id = cfg['horizons']['id']
    else: id = cfg['horizons']['name']
    obj = Horizons(id=id,
                   location=gs,
                   id_type=cfg['horizons']['id_type'],
                   epochs=cfg['horizons']['epochs'])
    eph = obj.ephemerides(quantities=cfg['horizons']['quantities'])
    keys = [
        'datetime_str', 'datetime_jd', 'AZ', 'AZ_rate', 'EL', 'EL_rate',
        'delta', 'delta_rate', 'lighttime'
    ]
    df = pd.DataFrame(np.array(eph[keys]), columns=keys)
    df['AZ_rate'] = df[
        'AZ_rate'] * 4.62963e-6  # arcsec per min to degrees per sec
    df['EL_rate'] = df[
        'EL_rate'] * 4.62963e-6  # arcsec per min to degrees per sec
    df['delta'] = df['delta'] * au2km  # AU to km
    df['lighttime'] = df['lighttime'] * 60  #minutes to seconds
    column_map = {
        'datetime_str': 'datetime_str [UTC]',
        'datetime_jd': 'datetime_jd [UTC]',
        'AZ': 'Azimuth [deg]',
        'AZ_rate': 'Azimuth Rate [deg/sec]',
        'EL': 'Elevation [deg]',
        'EL_rate': 'Elevation Rate [deg/sec]',
        'delta': 'Range [km]',
        'delta_rate': 'Range Rate [km/sec]',
        'lighttime': '1-Way Prop Delay [sec]'
    }
    df = df.rename(columns=column_map)
    df['datetime [ISO UTC]'] = pd.to_datetime(df['datetime_str [UTC]'],
                                              format="%Y-%b-%d %H:%M")
    return df
Ejemplo n.º 28
0
def get_current_pos(object_name, start_date, end_date, time_step):
    if 'COMET' in object_name:
        obj = Horizons(id=object_name[object_name.find(' ') + 1:],
                       epochs={
                           'start': start_time,
                           'stop': end_time,
                           'step': step
                       },
                       id_type='id')
    if not 'COMET' in object_name:
        obj = Horizons(id=object_name,
                       epochs={
                           'start': start_date,
                           'stop': end_date,
                           'step': time_step
                       })
    eph = obj.ephemerides()
    pos = SkyCoord(eph['RA'], eph['DEC'], unit='deg')
    vec = obj.vectors()
    times = Time(np.asarray(vec['datetime_jd']), format='jd', scale='utc')
    return np.asarray(pos.ra), np.asarray(pos.dec), times, np.asarray(
        eph['RA_rate']), np.asarray(eph['DEC_rate']), np.asarray(eph['V'])
Ejemplo n.º 29
0
def get_ephem_jpl(el_jpl, start, stop, obs):
    '''
    Parameters
    ----------
    el_jpl : `~numpy.ndarray` (N, 12)
        Orbital elements as returned by jpl.    
    start : `str`
        Beginning time of integration, UTC.   
    stop : `str`
        End time of integration, UTC.    
    obs : `str`
        Observatory code.
        
    Returns
    -------
    coord_jpl : `~numpy.ndarray` (N, 2)
        RA and DEC coordinates of ephemderides as determined by JPL, units deg
            RA : first column of coord_jpl
            DEC : second column of coord_jpl     
    mag_jpl : `~numpy.ndarray` (N, 1)
        Contains magnitudes of object as determined by JPL, units mags
    '''

    obj_id = el_jpl['targetname'][0]

    ephem_obj = Horizons(id=obj_id,
                         location=obs,
                         epochs={
                             'start': start,
                             'stop': stop,
                             'step': '1d'
                         })
    ephem_jpl = ephem_obj.ephemerides()

    coord_jpl = np.array([ephem_jpl['RA'], ephem_jpl['DEC']]) * u.deg
    mag_jpl = np.array([ephem_jpl['V']]) * u.mag

    return coord_jpl, mag_jpl
Ejemplo n.º 30
0
def getPlanetInfo(planet):
    obj = Horizons(id=planet, location='000', epochs=None, id_type='majorbody')
    eph = obj.ephemerides()
    return eph
Ejemplo n.º 31
0
def moving_primary_target(catalogs, man_targetname, offset, is_asteroid=None,
                          display=True):
    """
    is_asteroid == True:  this object is an asteroid
    is_asteroid == False: this object is a planet/moon/spacecraft
    is_asteroid == None:  no information on target nature
    """

    if display:
        print('# check JPL Horizons for primary target... ')
        sys.stdout.flush()
    logging.info('check JPL Horizons for primary target')

    obsparam = _pp_conf.telescope_parameters[
        catalogs[0].origin.split(';')[0].strip()]

    objects = []

    # check for target nature, if unknown
    if is_asteroid is None:
        cat = catalogs[0]
        targetname = cat.obj.replace('_', ' ')
        if man_targetname is not None:
            targetname = man_targetname.replace('_', ' ')
        for smallbody in [True, False]:
            obj = Horizons(targetname.replace('_', ' '),
                           id_type={True: 'smallbody',
                                    False: 'majorbody'}[smallbody],
                           epochs=cat.obstime[0],
                           location=obsparam['observatory_code'])
            n = 0
            try:
                eph = obj.ephemerides()
                n = len(eph)
            except ValueError:
                if display and smallbody is True:
                    print("'%s' is not a small body" % targetname)
                    logging.warning("'%s' is not a small body" %
                                    targetname)
                if display and smallbody is False:
                    print("'%s' is not a Solar System object" % targetname)
                    logging.warning("'%s' is not a Solar System object" %
                                    targetname)
                pass
            if n > 0:
                is_asteroid = smallbody
                break

    # if is_asteroid is still None, this object is not in the Horizons db
    if is_asteroid is None:
        return objects

    message_shown = False

    # query information for each image
    for cat_idx, cat in enumerate(catalogs):
        targetname = cat.obj.replace('_', ' ')
        if man_targetname is not None:
            targetname = man_targetname.replace('_', ' ')
            cat.obj = targetname
        obj = Horizons(targetname.replace('_', ' '),
                       id_type={True: 'smallbody',
                                False: 'majorbody'}[is_asteroid],
                       epochs=cat.obstime[0],
                       location=obsparam['observatory_code'])
        try:
            eph = obj.ephemerides()
            n = len(eph)
        except ValueError:
            # if is_asteroid:
            #     if display and not message_shown:
            #         print 'is \'%s\' an asteroid?' % targetname
            #     logging.warning('Target (%s) is not an asteroid' % targetname)

            # else:
            #     if display and not message_shown:
            #         print ('is \'%s\' a different Solar System object?' %
            #                )targetname
            #     logging.warning('Target (%s) is not a Solar System object' %
            #                     targetname)
            #     n = None
            pass

        if n is None or n == 0:
            logging.warning('WARNING: No position from Horizons! ' +
                            'Name (%s) correct?' % cat.obj.replace('_', ' '))
            logging.warning('HORIZONS call: %s' % obj.uri)
            if display and not message_shown:
                print('  no Horizons data for %s ' % cat.obj.replace('_', ' '))
                message_shown = True

        else:
            objects.append({'ident': eph[0]['targetname'].replace(" ", "_"),
                            'obsdate.jd': cat.obstime[0],
                            'cat_idx': cat_idx,
                            'ra_deg': eph[0]['RA']-offset[0]/3600,
                            'dec_deg': eph[0]['DEC']-offset[1]/3600})
            logging.info('Successfully grabbed Horizons position for %s ' %
                         cat.obj.replace('_', ' '))
            logging.info('HORIZONS call: %s' % obj.uri)
            if display and not message_shown:
                print(cat.obj.replace('_', ' '), "identified")
                message_shown = True

    return objects
Ejemplo n.º 32
0
def curve_of_growth_analysis(filenames, parameters,
                             display=False, diagnostics=False):

    output = {}
    obsparam = parameters['obsparam']

    logging.info('starting photometry with parameters: %s' %
                 (', '.join([('%s: %s' % (var, str(val))) for
                             var, val in list(locals().items())])))

    # re-extract sources for curve-of-growth analysis

    aprads = parameters['aprad']
    if not isinstance(aprads, list) and not isinstance(aprads, numpy.ndarray):
        print('need a list of aprads...')
        os.abort()

    logging.info('run pp_extract using %d apertures' % len(aprads))
    print('* extract sources from %d images using %d apertures' %
          (len(filenames), len(aprads)))

    extractparameters = {'sex_snr': parameters['sex_snr'],
                         'source_minarea': parameters['source_minarea'],
                         'paramfile': _pp_conf.rootpath
                         + '/setup/twentyapertures.sexparam',
                         'aprad': aprads, 'telescope': parameters['telescope'],
                         'quiet': False}

    extraction = pp_extract.extract_multiframe(filenames, extractparameters)
    extraction = [e for e in extraction if len(e) > 0]

    # curve-of-growth analysis

    # arrays for accumulating source information as a function of aprad
    background_flux = []  # numpy.zeros(len(aprads))
    target_flux = []  # numpy.zeros(len(aprads))
    background_snr = []  # numpy.zeros(len(aprads))
    target_snr = []  # numpy.zeros(len(aprads))

    for filename in filenames:

        if display:
            print('processing curve-of-growth for frame %s' % filename)

        if not parameters['background_only']:

            hdu = fits.open(filename, ignore_missing_end=True)

            # pull target coordinates from Horizons
            targetname = hdu[0].header[obsparam['object']]
            if parameters['manobjectname'] is not None:
                targetname = parameters['manobjectname'].translate(
                    _pp_conf.target2filename)

            image = hdu[0].data

            # derive MIDTIMJD, if not yet in the FITS header
            obsparam = parameters['obsparam']
            if not 'MIDTIMJD' in hdu[0].header:
                exptime = float(hdu[0].header[obsparam['exptime']])
                if obsparam['date_keyword'].find('|') == -1:
                    date = hdu[0].header[obsparam['date_keyword']]
                    date = dateobs_to_jd(date) + exptime/2./86400.
                else:
                    date_key = obsparam['date_keyword'].split('|')[0]
                    time_key = obsparam['date_keyword'].split('|')[1]
                    date = hdu[0].header[date_key]+'T' +\
                        hdu[0].header[time_key]
                    date = dateobs_to_jd(date) + exptime/2./86400.
            else:
                date = hdu[0].header['MIDTIMJD']

            # call HORIZONS to get target coordinates
            obj = Horizons(targetname.replace('_', ' '),
                           epochs=date,
                           location=str(obsparam['observatory_code']))
            try:
                eph = obj.ephemerides()
                n = len(eph)
            except ValueError:
                print('Target (%s) not a small body' % targetname)
                logging.warning('Target (%s) not a small body' % targetname)
                n = None

            if n is None or n == 0:
                logging.warning('WARNING: No position from Horizons!' +
                                'Name (%s) correct?' % targetname)
                logging.warning('HORIZONS call: %s' % obj.uri)
                logging.info('proceeding with background sources analysis')
                parameters['background_only'] = True
            else:
                logging.info('ephemerides for %s pulled from Horizons' %
                             targetname)
                target_ra, target_dec = eph[0]['RA'], eph[0]['DEC']

        # pull data from LDAC file
        ldac_filename = filename[:filename.find('.fit')]+'.ldac'
        data = catalog('Sextractor_LDAC')
        data.read_ldac(ldac_filename, maxflag=3)

        if data.shape[0] == 0:
            continue

        # identify target and extract its curve-of-growth
        n_target_identified = 0
        if not parameters['background_only']:
            residuals = numpy.sqrt((data['ra_deg']-target_ra)**2 +
                                   (data['dec_deg']-target_dec)**2)

            target_idx = numpy.argmin(residuals)
            if residuals[target_idx] > _pp_conf.pos_epsilon/3600:
                logging.warning(('WARNING: frame %s, large residual to ' +
                                 'HORIZONS position of %s: %f arcsec; ' +
                                 'ignore this frame') %
                                (filename, targetname,
                                 residuals[numpy.argmin(residuals)]*3600.))
            else:
                target_flux.append(data[target_idx]['FLUX_'+_pp_conf.photmode] /
                                   max(data[target_idx][
                                       'FLUX_'+_pp_conf.photmode]))
                target_snr.append(
                    data[target_idx]['FLUX_'+_pp_conf.photmode] /
                    data[target_idx]['FLUXERR_'+_pp_conf.photmode] /
                    max(data[target_idx]['FLUX_'+_pp_conf.photmode] /
                        data[target_idx]['FLUXERR_'+_pp_conf.photmode]))
                n_target_identified += 1

        # extract background source fluxes and snrs
        #   assume n_background_sources >> 1, do not reject target
        if not parameters['target_only']:
            # n_src = data.shape[0] # use all sources
            n_src = 50  # use only 50 sources
            for idx, src in enumerate(data.data[:n_src]):
                if (numpy.any(numpy.isnan(src['FLUX_'+_pp_conf.photmode])) or
                    numpy.any(numpy.isnan(src['FLUXERR_'+_pp_conf.photmode]))
                        or src['FLAGS'] > 3):
                    continue

                # create growth curve
                background_flux.append(src['FLUX_'+_pp_conf.photmode] /
                                       max(src['FLUX_'+_pp_conf.photmode]))
                background_snr.append(src['FLUX_'+_pp_conf.photmode] /
                                      src['FLUXERR_'+_pp_conf.photmode] /
                                      max(src['FLUX_'+_pp_conf.photmode] /
                                          src['FLUXERR_'+_pp_conf.photmode]))

    # investigate curve-of-growth

    logging.info('investigate curve-of-growth based on %d frames' %
                 len(filenames))

    # combine results
    n_target = len(target_flux)
    if n_target > 0:
        target_flux = (numpy.median(target_flux, axis=0),
                       numpy.std(target_flux, axis=0)/numpy.sqrt(n_target))
        target_snr = numpy.median(target_snr, axis=0)
    else:
        target_flux = (numpy.zeros(len(aprads)), numpy.zeros(len(aprads)))
        target_snr = numpy.zeros(len(aprads))

    n_background = len(background_flux)
    if n_background > 0:
        background_flux = (numpy.median(background_flux, axis=0),
                           numpy.std(background_flux, axis=0) /
                           numpy.sqrt(n_background))
        background_snr = numpy.median(background_snr, axis=0)
    else:
        background_flux = (numpy.zeros(len(aprads)), numpy.zeros(len(aprads)))
        background_snr = numpy.zeros(len(aprads))

    if n_target == 0:
        logging.info('No target fluxes available, using background sources, ' +
                     'only')
        parameters['background_only'] = True

    if n_background == 0:
        logging.info('No background fluxes available, using target, only')
        parameters['target_only'] = True

    # find optimum aperture radius
    if parameters['target_only']:
        aprad_strategy = 'smallest target aprad that meets fluxlimit criterion'
        optimum_aprad_idx = numpy.argmin(numpy.fabs(target_flux[0] -
                                                    _pp_conf.fluxlimit_aprad))
    elif parameters['background_only']:
        aprad_strategy = 'smallest background aprad that meets fluxlimit ' + \
                         'criterion'
        optimum_aprad_idx = numpy.argmin(numpy.fabs(background_flux[0] -
                                                    _pp_conf.fluxlimit_aprad))
    else:
        # flux_select: indices where target+background fluxes > fluxlimit
        flux_select = numpy.where((target_flux[0] > _pp_conf.fluxlimit_aprad) &
                                  (background_flux[0] > _pp_conf.fluxlimit_aprad))[0]
        flux_res = numpy.fabs(target_flux[0][flux_select] -
                              background_flux[0][flux_select])

        if numpy.min(flux_res) < _pp_conf.fluxmargin_aprad:
            aprad_strategy = 'target+background fluxes > fluxlimit, ' + \
                             'flux difference < margin'
            optimum_aprad_idx = flux_select[numpy.where(flux_res <
                                                        _pp_conf.fluxmargin_aprad)[0][0]]
        else:
            aprad_strategy = 'target+background fluxes > fluxlimit, ' + \
                             'flux difference minimal'
            optimum_aprad_idx = flux_select[numpy.argmin(flux_res)]

    optimum_aprad = parameters['aprad'][optimum_aprad_idx]

    output['aprad_strategy'] = aprad_strategy
    output['optimum_aprad'] = optimum_aprad
    output['pos_epsilon'] = _pp_conf.pos_epsilon
    output['fluxlimit_aprad'] = _pp_conf.fluxlimit_aprad
    output['fluxmargin_aprad'] = _pp_conf.fluxmargin_aprad
    output['n_target'] = len(target_flux[0])
    output['n_bkg'] = len(background_flux[0])
    output['target_flux'] = target_flux
    output['target_snr'] = target_snr
    output['background_flux'] = background_flux
    output['background_snr'] = background_snr
    output['parameters'] = parameters

    # write results to file
    outf = open('aperturephotometry_curveofgrowth.dat', 'w')
    outf.writelines('#      background              target          flux\n' +
                    '# rad   flux sigma snr      flux sigma snr  residual\n')
    for i in range(len(parameters['aprad'])):
        outf.writelines(('%5.2f  %5.3f %5.3f %4.2f   %6.3f %5.3f %4.2f   ' +
                         '%6.3f\n') %
                        (parameters['aprad'][i], background_flux[0][i],
                         background_flux[1][i], background_snr[i],
                         target_flux[0][i], target_flux[1][i],
                         target_snr[i],
                         target_flux[0][i]-background_flux[0][i]))
    outf.close()

    # extraction content
    #
    # -> see pp_extract.py
    #
    ###

    # output content
    #
    # { 'aprad_strategy'  : optimum aperture finding strategy,
    #   'optimum_aprad'   : optimum aperature radius,
    #   'pos_epsilon'     : required positional uncertainty ("),
    #   'fluxlimit_aprad' : min flux for both target and background,
    #   'fluxmargin_aprad': max flux difference between target and background,
    #   'n_target'        : number of frames with target flux measurements,
    #   'n_bkg'           : number of frames with background measurements,
    #   'target_flux'     : target fluxes as a function of aprad,
    #   'target_snr'      : target snrs as a function of aprad,
    #   'background_flux' : background fluxes as a function of aprad,
    #   'background_snr'  : background snrs as a function of aprad,
    #   'parameters'      : source extractor parameters
    # }
    ###

    # diagnostics
    if diagnostics:
        if display:
            print('creating diagnostic output')
        logging.info(' ~~~~~~~~~ creating diagnostic output')
        diag.add_photometry(output, extraction)

    # update image headers
    for filename in filenames:
        hdu = fits.open(filename, mode='update', ignore_missing_end=True)
        hdu[0].header['APRAD'] = (optimum_aprad, 'aperture phot radius (px)')
        hdu[0].header['APIDX'] = (optimum_aprad_idx, 'optimum aprad index')
        hdu.flush()
        hdu.close()

    # display results
    if display:
        print('\n#################################### PHOTOMETRY SUMMARY:\n###')
        print('### best-fit aperture radius %5.2f (px)' % (optimum_aprad))
        print('###\n#####################################################\n')

    logging.info('==> best-fit aperture radius: %3.1f (px)' % (optimum_aprad))

    return output
Ejemplo n.º 33
0
def combine(filenames, obsparam, comoving, targetname,
            manual_rates, combine_method, keep_files,
            backsub=False, display=True, diagnostics=True):
    """
    image combination wrapper
    output: diagnostic properties
    """

    # start logging
    logging.info('starting image combination with parameters: %s' %
                 (', '.join([('%s: %s' % (var, str(val))) for
                             var, val in list(locals().items())])))

    # check if images have been run through pp_prepare
    try:
        midtime_jd = fits.open(filenames[0], verify='silentfix',
                               ignore_missing_end=True)[0].header['MIDTIMJD']
    except KeyError:
        raise KeyError(('%s image header incomplete, have the data run ' +
                        'through pp_prepare?') % filenames[0])
        return None

    # adopt first frame as reference frame
    hdulist = fits.open(filenames[0])
    header = hdulist[0].header
    refdate = float(header['MIDTIMJD'])
    # read out ra and dec from header
    if obsparam['radec_separator'] == 'XXX':
        ref_ra_deg = float(header[obsparam['ra']])
        ref_dec_deg = float(header[obsparam['dec']])
        if obsparam['telescope_keyword'] == 'UKIRTWFCAM':
            ref_ra_deg = ref_ra_deg/24.*360. - 795/3600.
            ref_dec_deg -= 795/3600.
    else:
        ra_string = header[obsparam['ra']].split(
            obsparam['radec_separator'])
        dec_string = header[obsparam['dec']].split(
            obsparam['radec_separator'])
        ref_ra_deg = 15.*(float(ra_string[0]) +
                          old_div(float(ra_string[1]), 60.) +
                          old_div(float(ra_string[2]), 3600.))
        ref_dec_deg = (abs(float(dec_string[0])) +
                       old_div(float(dec_string[1]), 60.) +
                       old_div(float(dec_string[2]), 3600.))
        if dec_string[0].find('-') > -1:
            ref_dec_deg = -1 * ref_dec_deg

    if obsparam['telescope_keyword'] == 'UKIRTWFCAM':
        ref_ra_deg = ref_ra_deg/24.*360.

    if obsparam['telescope_keyword'] == "UKIRTWFCAM":
        ref_ra_deg -= float(header['TRAOFF'])/3600
        ref_dec_deg -= float(header['TDECOFF'])/3600

    hdulist.close()

    # modify individual frames if comoving == True
    if comoving:
        movingfilenames = []

        # sort filenames by MIDTIMJD
        mjds = []
        for filename in filenames:
            hdulist = fits.open(filename)
            mjds.append(float(hdulist[0].header['MIDTIMJD']))
        filenames = [filenames[i] for i in numpy.argsort(mjds)]

        for filename in filenames:
            movingfilename = filename[:filename.find('.fits')]+'_moving.fits'
            print('shifting %s -> %s' % (filename, movingfilename))
            logging.info('shifting %s -> %s' % (filename, movingfilename))

            # read out date and pointing information
            hdulist = fits.open(filename)
            header = hdulist[0].header
            date = hdulist[0].header['MIDTIMJD']
            data = hdulist[0].data
            hdulist.close()

            # use ephemerides from Horizons if no manual rates are provided
            if manual_rates is None:
                # call HORIZONS to get target coordinates
                obj = Horizons(targetname.replace('_', ' '), epochs=date,
                               location=str(obsparam['observatory_code']))
                try:
                    eph = obj.ephemerides()
                    n = len(eph)
                except ValueError:
                    print('Target (%s) not an asteroid' % targetname)
                    logging.warning('Target (%s) not an asteroid' % targetname)
                    n = None

                if n is None or n == 0:
                    logging.warning('WARNING: No position from Horizons!' +
                                    'Name (%s) correct?' % targetname)
                    logging.warning('HORIZONS call: %s' % eph.url)
                    raise(ValueError, 'no Horizons ephemerides available')
                else:
                    logging.info('ephemerides for %s pulled from Horizons' %
                                 targetname)
                    logging.info('Horizons call: %s' %
                                 obj.uri)

                    target_ra, target_dec = eph[0]['RA'], eph[0]['DEC']

                # get image pointing from header
                if obsparam['radec_separator'] == 'XXX':
                    ra_deg = float(header[obsparam['ra']])
                    dec_deg = float(header[obsparam['dec']])
                    if obsparam['telescope_keyword'] == 'UKIRTWFCAM':
                        ra_deg = ra_deg/24.*360. - 795/3600.
                        dec_deg -= 795/3600.
                else:
                    ra_string = header[obsparam['ra']].split(
                        obsparam['radec_separator'])
                    dec_string = header[obsparam['dec']].split(
                        obsparam['radec_separator'])
                    ra_deg = 15.*(float(ra_string[0]) +
                                  old_div(float(ra_string[1]), 60.) +
                                  old_div(float(ra_string[2]), 3600.))
                    dec_deg = (abs(float(dec_string[0])) +
                               old_div(float(dec_string[1]), 60.) +
                               old_div(float(dec_string[2]), 3600.))
                    if dec_string[0].find('-') > -1:
                        dec_deg = -1 * dec_deg

                if filename == filenames[0]:
                    ref_offset_ra = target_ra - ref_ra_deg
                    ref_offset_dec = target_dec - ref_dec_deg

                offset_ra = target_ra - ref_ra_deg - ref_offset_ra
                offset_dec = target_dec - ref_dec_deg - ref_offset_dec

            else:
                # use manual rates (since they are provided)
                offset_ra = ((float(header['MIDTIMJD'])-refdate)*86400 *
                             float(manual_rates[0]))/3600
                offset_dec = ((float(header['MIDTIMJD'])-refdate)*86400 *
                              float(manual_rates[1]))/3600

            logging.info('offsets in RA and Dec: %f, %f arcsec' %
                         (offset_ra*3600, offset_dec*3600))

            crval1 = float(header['CRVAL1'])
            crval2 = float(header['CRVAL2'])

            # write new CRVALi keywords in different file
            new_hdu = fits.PrimaryHDU(data)
            new_hdu.header = header
            new_hdu.header['CRVAL1'] = (crval1-offset_ra,
                                        'updated in the moving frame of the object')
            new_hdu.header['CRVAL2'] = (crval2-offset_dec,
                                        'updated in the moving frame of the object')
            movingfilenames.append(movingfilename)
            new_hdu.writeto(movingfilename, overwrite=True,
                            output_verify='silentfix')

    if comoving:
        outfile_name = 'comove.fits'
        fileline = " ".join(movingfilenames)
        n_frames = len(movingfilenames)
    else:
        outfile_name = 'skycoadd.fits'
        fileline = " ".join(filenames)
        n_frames = len(filenames)

    # run swarp on all image catalogs using different catalogs
    commandline = (('swarp -combine Y -combine_type %s -delete_tmpfiles ' +
                    'Y -imageout_name %s -interpolate Y -subtract_back %s ' +
                    '-weight_type NONE -copy_keywords %s -write_xml N ' +
                    '-CENTER_TYPE MOST %s') %
                   ({'median': 'MEDIAN', 'average': 'AVERAGE',
                     'clipped': 'CLIPPED -CLIP_AMPFRAC 0.2 -CLIP_SIGMA 0.1 '}
                    [combine_method],
                    outfile_name,
                    {True: 'Y', False: 'N'}[backsub],
                    obsparam['copy_keywords'], fileline))

    logging.info('call SWARP as: %s' % commandline)
    print('running SWARP to combine {:d} frames...'.format(n_frames))

    try:
        swarp = subprocess.Popen(shlex.split(commandline),
                                 stdout=DEVNULL,
                                 stderr=DEVNULL,
                                 close_fds=True)
        # do not direct stdout to subprocess.PIPE:
        # for large FITS files, PIPE will clog, stalling
        # subprocess.Popen
    except Exception as e:
        print('SWARP call:', (e))
        logging.error('SWARP call:', (e))
        return None

    swarp.wait()
    print('done!')

    # remove files that are not needed anymore
    if not keep_files:
        if comoving:
            for filename in movingfilenames:
                os.remove(filename)

    # update combined image header
    total_exptime = 0
    for filename in filenames:
        hdulist = fits.open(filename)
        total_exptime += float(hdulist[0].header[obsparam['exptime']])

    hdulist = fits.open(outfile_name, mode='update')
    hdulist[0].header[obsparam['exptime']] = (total_exptime, 'PP: cumulative')
    hdulist[0].header['COMBO_N'] = (len(filenames), 'PP: N files combo')
    hdulist[0].header['COMBO_M'] = (combine_method, 'PP: combo method')
    hdulist[0].header['COMOVE'] = (str(comoving), 'PP: comoving?')
    hdulist.flush()

    return n_frames