예제 #1
0
def getteff(c,cone=10):

    G = nan
    while G != G and cone < 180:
       print "cone search radius",cone
       #if True:
       try:
           width = u.Quantity(cone, u.arcsec)
           height = u.Quantity(cone, u.arcsec)
           result = Gaia.cone_search_async(c,width)
           result =  result.get_results()
           #print result.columns

           useindx = 0
           print "len result",len(result)
           if len(result) > 1:
               Gmag = []
               for i in range(len(result)):
                   Gmag.append(result[i]["phot_g_mean_mag"])
               Gmag = array(Gmag)
               print Gmag
               useindx = argmin(Gmag)

           G =  result[useindx]["phot_g_mean_mag"]
           teff =  result[useindx]["teff_val"]
           rstar = result[useindx]["radius_val"]

       except IndexError:
           G = nan
           teff = nan
           rstar = nan

       cone += 20
        
    return teff,rstar,G
예제 #2
0
def get_GAIA_data(coord, radius):
    """Query Gaia database.

    Parameters
    ----------
    coord  : SkyCoord
        Position to search.
    radius : float
        Radius of search cone.

    Returns
    -------
    objects
        table with the objects including the following info: ra (deg), ra_error (milliarcsec), dec (deg), dec_error (milliarcsec), mag

    """
    j = Gaia.cone_search_async(coord, radius)
    r = j.get_results()
    #r.pprint()
    #r.show_in_browser()

    catalog_data = r.to_pandas()
    catalog_data["mag"] = catalog_data["phot_g_mean_mag"]
    catalog_data = catalog_data[["ra", "ra_error", "dec", "dec_error", "mag"]]
    print("Found {} sources in GAIA within a radius of {}".format(
        catalog_data.shape[0], radius))
    #columns: ra, ra_error, dec, dec_error, mag
    return catalog_data
    def select_sources_from_gaia():
        # Use some set of criteria to choose sources for measurement.

        coord = astropy.coordinates.SkyCoord(hdr['CRVAL1'],hdr['CRVAL2'],unit='deg')
        result = Gaia.cone_search_async(coord,radius=10*u.arcminute)
        catalog = result.get_data()
        pass
    def _select_stars_for_psf(self, sscat, imfile):
        '''
        method to obtain stars from SExtractor catalog by comparing to GAIA
            sscat : input ldac-format catalog from which to select stars
            imfile : image file on which sscat is based; needed for header's CRVAL kw
        '''
        # Read in header, get catalog of GAIA sources that overlap the field, ish.

        hdr = fits.getheader(imfile)
        coord = astropy.coordinates.SkyCoord(hdr['CRVAL1'],
                                             hdr['CRVAL2'],
                                             unit='deg')
        result = Gaia.cone_search_async(coord, radius=14 * u.arcminute)
        catalog = result.get_data()
        catalog_wg = catalog[catalog['parallax'] >= catalog['parallax_error']]
        # get RA/Dec of input catalog, cross-match against GAIA
        ss = fits.open(sscat)
        sexmatcher = eu.htm.Matcher(16,
                                    ra=ss[2].data['ALPHAWIN_J2000'],
                                    dec=ss[2].data['DELTAWIN_J2000'])
        gaia_matches, sexmatches, dist = sexmatcher.match(catalog_wg['ra'],
                                                          catalog_wg['dec'],
                                                          radius=6E-4,
                                                          maxmatch=1)
        # Save result to file, return filename
        outname = sscat.replace('.ldac', '.star')
        ss[2].data = ss[2].data[sexmatches]
        ss.writeto(outname, overwrite=True)

        return outname
예제 #5
0
    def make_psf_models(self):
        """ 
        Start by making reference star file for later psfcat matching 
        This arrangement is special to DECam data of a single cluster, 
        where all images will have roughly the same center
        """
        hdr = fits.getheader(self.image_files[0])
        coord = astropy.coordinates.SkyCoord(hdr['CRVAL1'],
                                             hdr['CRVAL2'],
                                             unit='deg')
        result = Gaia.cone_search_async(coord, radius=1.2 * u.degree)
        catalog = result.get_data()
        catalog_wg = catalog[catalog['parallax'] >= catalog['parallax_error']]
        """
        now do actual PSF modelling
        """

        self.psfEx_models = []
        for i, imagefile in enumerate(self.image_files):
            weightfile = self.weight_files[i]
            psfex_model_file = self._make_psf_model(imagefile,
                                                    weightfile=weightfile,
                                                    star_reference=catalog_wg)
            # move checkimages to psfex_output
            cmd = ' '.join(['mv chi* resi* samp* snap* proto*', self.psf_path])
            os.system(cmd)

            try:
                self.psfEx_models.append(psfex.PSFEx(psfex_model_file))
            except:
                pdb.set_trace()
예제 #6
0
def cone_search(
    *,
    name=None,
    radius=None,
    ra=None,
    dec=None,
    columns=[
        "ra",
        "ra_error",
        "dec",
        "dec_error",
        "parallax",
        "parallax_error",
        "pmra",
        "pmra_error",
        "pmdec",
        "pmdec_error",
    ],
    dump_to_file=False,
    row_limit=50,
    **kwargs,
):
    if not isinstance(radius, (float, int)):
        raise ValueError("radious must be specified with int or float")
    else:
        radius = u.Quantity(radius, u.degree)
    if not ((name is not None) ^ (ra is not None and dec is not None)):
        raise ValueError("'name' or 'ra' and 'dec' are required (not both)")
    if name is not None:
        if not isinstance(name, str):
            raise ValueError("name must be string")
        else:
            coord = simbad_search(name)
    if (ra, dec) != (None, None):
        if not isinstance(ra,
                          (float, int)) or not isinstance(dec, (float, int)):
            raise ValueError("ra and dec must be numeric")
        else:
            coord = SkyCoord(ra, dec, unit=(u.degree, u.degree), frame="icrs")
    if not isinstance(row_limit, int):
        raise ValueError("row_limit must be int")
    """ elif row_limit == -1:
        warnings.warn("Row limit set to unlimited.")
    """
    Gaia.ROW_LIMIT = row_limit

    job = Gaia.cone_search_async(
        coordinate=coord,
        radius=radius,
        columns=columns,
        dump_to_file=dump_to_file,
        **kwargs,
    )

    if not dump_to_file:
        table = job.get_results()
        return table
예제 #7
0
def checkNeighbor(variableRa, variableDec, sourceId):
    coord = SkyCoord(ra=variableRa,
                     dec=variableDec,
                     unit=(u.degree, u.degree),
                     frame='icrs')
    radius = u.Quantity(0.00138889, u.deg)
    j = Gaia.cone_search_async(coord, radius)
    r = j.get_results()
    if len(r['ra']) > 1:
        for neighbor in range(len(r['ra'])):
            #make sure neighbor is different from target star
            if r['source_id'][neighbor] != sourceId:
                return 1

    return 0
예제 #8
0
def find_in_gaia(ra, dec):
    # First do a large search using 30 arcsec
    coord = SkyCoord(ra=ra, dec=dec, unit=(u.degree, u.degree), frame='icrs')
    radius = u.Quantity(30.0, u.arcsec)
    q = Gaia.cone_search_async(coord, radius)
    gaia = q.get_results()
    gaia = gaia[np.nan_to_num(gaia['parallax']) > 0]
    warning = (len(gaia) == 0)

    # Then propagate the Gaia coordinates to 2000, and find the best match to the
    # input coordinates
    if not warning:
        ra2015 = np.array(gaia['ra']) * u.deg
        dec2015 = np.array(gaia['dec']) * u.deg
        parallax = np.array(gaia['parallax']) * u.mas
        pmra = np.array(gaia['pmra']) * u.mas / u.yr
        pmdec = np.array(gaia['pmdec']) * u.mas / u.yr
        c2015 = SkyCoord(ra=ra2015,
                         dec=dec2015,
                         distance=Distance(parallax=parallax,
                                           allow_negative=True),
                         pm_ra_cosdec=pmra,
                         pm_dec=pmdec,
                         obstime=Time(2015.5, format='decimalyear'))
        c2000 = c2015.apply_space_motion(dt=-15.5 * u.year)

        idx, sep, _ = coord.match_to_catalog_sky(c2000)

        # The best match object
        best = gaia[idx]
        gaia_id = best['source_id']

        MG = 5 + 5 * np.log10(
            best['parallax'] / 1000) + best['phot_g_mean_mag']
        bprp = best['bp_rp']

        gaia_id = np.int(gaia_id)
        G = np.float(best['phot_g_mean_mag'])
        MG = np.float(MG)
        bprp = np.float(bprp)

        return gaia_id, G, MG, bprp
예제 #9
0
    def query_gaia(self, n_stars=1000):
        from astroquery.gaia import Gaia

        header = fits.getheader(self.stack_fits)
        shape = fits.getdata(self.stack_fits).shape
        cone_radius = np.sqrt(2) * np.max(shape) * self.telescope.pixel_scale / 120
        wcs = WCS(header)

        coord = self.skycoord
        radius = u.Quantity(cone_radius, u.arcminute)
        gaia_query = Gaia.cone_search_async(coord, radius, verbose=False, )
        self.gaia_data = gaia_query.get_results()

        skycoords = SkyCoord(
            ra=self.gaia_data['ra'],
            dec=self.gaia_data['dec'],
            pm_ra_cosdec=self.gaia_data['pmra'],
            pm_dec=self.gaia_data['pmdec'],
            radial_velocity=self.gaia_data['radial_velocity'])

        self.gaia_data["x"], self.gaia_data["y"] = np.array(wcsutils.skycoord_to_pixel(skycoords, self.wcs))
예제 #10
0
def checkNeighbor(variableRa, variableDec, sourceId):
    coord = SkyCoord(ra=variableRa, dec=variableDec, unit=(u.degree, u.degree), frame='icrs')
    radius = u.Quantity(0.00138889, u.deg)
    j = Gaia.cone_search_async(coord, radius)
    r = j.get_results()
    if len(r['ra']) > 1:
        for neighbor in range(len(r['ra'])):
            #make sure neighbor is different from target star
            if r['source_id'][neighbor] != sourceId:
                # flag star brighter than 8 magnitude within 50"
                if r['phot_g_mean_mag'][neighbor] < 8:
                    return 1
                # flag star brighter than 12 magnitude within 30"
                elif r['dist'][neighbor] < 0.00833333 and r['phot_g_mean_mag'][neighbor] < 12:
                    return 1
                # flag star brighter than 20 magnitude within 10"
                elif r['dist'][neighbor] < 0.00277778 and r['phot_g_mean_mag'][neighbor] < 20:
                    return 1
                 # flag star within 5"
                elif r['dist'][neighbor] < 0.00138889:
                    return 1

    return 0
예제 #11
0
def get_gaia_data(coord, approx_mag=None, radius=None, mag_tol=1.0, **kwargs):
    """Cross match to Gaia and construct a dataset for isochrone fitting

    Args:
        coord (SkyCoord): The coordinates of the source
        approx_mag (float, optional): The magnitude of the source in an
            optical band. If provided, only sources with a Gaia G mag within
            ``mag_tol`` mag will be returned.
        mag_tol (float, optional): The magnitude tolerance.
        radius (Quantity, optional): The angular search radius.

    Raises:
        ValueError: If no match is found or if any of the parameters are not
            finite in the catalog.

    Returns:
        The data dictionary

    """
    # coord = SkyCoord(ra=toi.RA, dec=toi.Dec, unit=(u.hourangle, u.deg))
    if radius is None:
        radius = 20 * u.arcsec
    j = Gaia.cone_search_async(coord, radius)
    r = j.get_results()

    # Only select targets within 1 mag of the target
    if approx_mag is not None:
        r = r[np.abs(r["phot_g_mean_mag"] - approx_mag) < mag_tol]

    if not len(r):
        raise ValueError("no matches found")

    # Select the closest target
    r = r[0]

    return _parse_gaia_data(r, **kwargs)
예제 #12
0
 def _get_gaia_id(ra, dec, radius):
     c = SkyCoord(ra, dec, unit=(u.deg, u.deg), frame='icrs')
     j = Gaia.cone_search_async(c, radius)
     res = j.get_results()
     return res['source_id'][0]
예제 #13
0
def get_gaia_data(coord, approx_mag=None, radius=None, **kwargs):
    """Cross match to Gaia and construct a dataset for isochrone fitting

    Args:
        coord (SkyCoord): The coordinates of the source
        approx_mag (float, optional): The magnitude of the source in an
            optical band. If provided, only sources with a Gaia G mag within
            1 mag will be returned.
        radius (Quantity, optional): The angular search radius.

    Raises:
        ValueError: If no match is found or if any of the parameters are not
            finite in the catalog.

    Returns:
        The data dictionary

    """
    # coord = SkyCoord(ra=toi.RA, dec=toi.Dec, unit=(u.hourangle, u.deg))
    if radius is None:
        radius = 20 * u.arcsec
    j = Gaia.cone_search_async(coord, radius)
    r = j.get_results()

    # Only select targets within 1 mag of the target
    if approx_mag is not None:
        r = r[np.abs(r["phot_g_mean_mag"] - approx_mag) < 1]

    if not len(r):
        raise ValueError("no matches found")

    # Select the closest target
    r = r[0]

    # Parallax offset reference: https://arxiv.org/abs/1805.03526
    plx = r["parallax"] + 0.082
    plx_err = np.sqrt(r["parallax_error"] ** 2 + 0.033 ** 2)
    if not (np.isfinite(plx) and np.isfinite(plx_err)):
        raise ValueError("non finite parallax")

    # Convert flux error to magnitude error by linear propagation, this
    # should be ok for bright sources
    factor = 2.5 / np.log(10)
    params = {}
    for band in ["G", "BP", "RP"]:
        mag = float(r["phot_{0}_mean_mag".format(band.lower())])
        err = float(r["phot_{0}_mean_flux_error".format(band.lower())])
        err /= float(r["phot_{0}_mean_flux".format(band.lower())])
        err *= factor
        if not (np.isfinite(mag) and np.isfinite(err)):
            raise ValueError("non finite params")
        params[band] = (mag, err)

    params["parallax"] = (float(plx), float(plx_err))

    # Make sure that the dtypes are all correct
    for k, v in params.items():
        params[k] = np.array(v, dtype=np.float64)
    if params["parallax"][0] > 0:
        params["max_distance"] = np.clip(2000 / plx, 100, np.inf)

    params = dict(params, **kwargs)

    return params
예제 #14
0
def query(coordi, photo_filters, CCD_structure, exposure_time, catalog):
    '''
    This funtion uses all the functions above to query Simbad and extract the information about the stars in a
    specific area of the sky

    Parameters
    ----------

    coordi : string
        It contains the center of the area of interest

    photo_filter : list (string elements)
        It is a list where a element is a string that identifies a filter, e.g. "U","R","I"

    CCD_structure : array (float elements)
        This object contains the information about the measure of the CCD
        [0] : the length of the CCD on the x axis in mm
        [1] : the length of the CCD on the y axis in mm
        [2] : the length of a single pixel in mm

    exposure_time : int
        It is the exposure time used to obtain the image, it is in seconds

    Outputs
    -------

    data : list
        It is a list of array that contains
         [0] : array, the position of the stars along the x axis
         [1] : array, the position of the stars along the y axis
         [2] : array, the number of electrons generates by the stars on the CCD

    center : list
        It contains the center of the sky portion in "RA" and "DEC"
    '''
    log.info(hist())
    
    radius = radius_sky_portion(CCD_structure)
    coordi = coord.SkyCoord(coordi, frame = 'icrs', unit=(u.hourangle, u.deg))

    center = [0,0]
    center[0] = coordi.ra.degree
    center[1] = coordi.dec.degree
    data = Data_structure()
    AirMass = 1 #simple Antola

    if catalog == 'Simbad':
        Controll_V = False

        for n, i in enumerate(photo_filters):
            if i == "g":
                photo_filters[n] = "V"

        photo_filters_temp = photo_filters
    
        if "V" in photo_filters_temp:
            photo_filters_temp.append("g")
            Controll_V = True

        f =['flux({0})'.format(x) for x in photo_filters_temp]
        [Simbad.add_votable_fields(g) for g in f]
        result_table = Simbad.query_region(coordi, radius)

        Stars_number = len(result_table)
        len_filter_list = len(photo_filters_temp)
        
        if Controll_V:
            log.warning('If filter V is not available, g filter will be used instead')
            log.info(hist(f"Creating {Stars_number} stars:"))
        for i in range(Stars_number):

            log.info(f"Star n° {i+1}/{Stars_number}")
            row = result_table[i]
            tot = 0
            magnitudo = []
            for j in range(11, 11+len_filter_list):  #controll
                if row[j] is np.ma.masked:
                    row[j] = 0
                magnitudo.append(row[j])
        
            tot = magnitudo_to_electrons(magnitudo, photo_filters_temp, AirMass, exposure_time, Controll_V)
    
            if tot != 0: #if total flux is 0 the object is not passed
                c = coord.SkyCoord(row[1], row[2], frame = 'icrs', unit=(u.hourangle, u.deg))##change here
                x, y = Coordinator(c, center, CCD_structure, catalog)
                data[0].append(x)
                data[1].append(y)
                data[2].append(tot)
    elif catalog == 'Gaia':
        Gaia.ROW_LIMIT = -1
        tables = Gaia.cone_search_async(coordi, radius)
        tables = tables.get_results()
        photonis = tables['phot_g_mean_flux'][:]
        mag = tables['phot_g_mean_mag'][:]
        pos_ra = tables['ra'][:]
        pos_dec = tables['dec'][:]
        number_of_stars = len(photonis)
        for i in range(number_of_stars):
            c = coord.SkyCoord(pos_ra[i], pos_dec[i], frame = 'icrs', unit=(u.degree, u.degree))
            x, y = Coordinator(c, center, CCD_structure, catalog)
            mag_atm_att = AirMass*0.2   #extinction_coefficient_mean
            mag[i] = mag[i] + mag_atm_att
            mag[i] = 10**(6.74-0.4*mag[i]) #here becomes photons
            quantum_efficiency = 0.3
            transmissivity = 0.5              
            multiplier = quantum_efficiency * transmissivity * exposure_time *0.5
            data[0].append(x)
            data[1].append(y)
            data[2].append(mag[i] * multiplier)
    return data, center
예제 #15
0
    #

    # match the catalog - ignore all sources with multiple counterparts

    # tree = scipy.spatial.KDTree(catalog[:, 2:4])

    # get ra/dec from reference
    center_pos = wcs.getCentreWCSCoords()
    print center_pos

    coord = astropy.coordinates.SkyCoord(ra=center_pos[0],
                                         dec=center_pos[1],
                                         unit=(u.degree, u.degree),
                                         frame='fk5')
    radius = Quantity(4.0, u.arcmin)
    j = Gaia.cone_search_async(coord, radius)
    r = j.get_results()
    # r.pprint()

    #try:
    #print r[r.keys()[0]]['ra']
    print r['ra']
    print r['dec']
    #except:
    #    pass

    for iteration in range(3):

        # convert the x/y from HST into ra/dec using the latest and greatest WCS
        astro_wcs = astropy.wcs.WCS(header=ext.header)
예제 #16
0
def make_gaia(coords,
              image=os.path.join('.', 'synthetic_gaia.fits'),
              epoch="J2020.5"):
    """
    Creates a synthetic image from GAIA DR2 photometry along the specified coordinates.

    Returns the synthetic image in fits format.

    Parameters:
    coords: Coordinates of centre of image.
    image: File name of image. Default is synthetic_gaia.fits
    epoch: Epoch to translate image. Default is J2020.5
    """
    #####
    ##### Define GMOS parameters
    ##### GMOS FoV is 330 arcsec
    ##### GMOS slit length is 330 arcsec
    ##### GMOS fwhm chosen in 0.3 arcsec
    ##### Image created is 390 arcsec, to accomadte additional overlays
    ##### GMOS read noise is 3.96  (e-/ADU)
    ##### GMOS gain is 1.829  (e- rms)
    #####

    gmosfov = 390 * u.arcsec
    fwhm = 0.3 * u.arcsec
    shape = (1300, 1300)
    zeroarr = np.zeros(shape)
    width = 390 * u.arcsec
    height = 390 * u.arcsec

    ##### Read coordinates and epoch
    coords = coords
    epoch = Time(epoch, format='jyear_str')

    ##### Query GAIA DR2 using astroquery TAP+
    ##### Synchronous query, limit of 2000 rows
    print('Searching GAIA TAP+ for stars over the GMOS FoV...')
    gaiasearch = Gaia.cone_search_async(coordinate=coords,
                                        radius=gmosfov,
                                        verbose=False)
    searchresults = gaiasearch.get_results()
    nstars = len(searchresults)
    print(nstars, 'stars recovered from GAIA TAP+ query over the GMOS FoV')
    if nstars == 2000:
        warnings.warn(
            'Asynchronous TAP+ service query limit reached, image is incomplete.'
        )

    fitshdr = mkfitshdr(coords, zeroarr, image, epoch)
    hdr = fitshdr[0]
    hdu = fitshdr[1]
    hdul = fitshdr[2]
    w = fitshdr[3]

    c = SkyCoord(ra=searchresults['ra'],
                 dec=searchresults['dec'],
                 pm_ra_cosdec=searchresults['pmra'],
                 pm_dec=searchresults['pmdec'],
                 obstime=Time(searchresults['ref_epoch'],
                              format='decimalyear'))

    cnew = c
    ###### in the current implementation, transformation of the image to the epoch is not applied

    ######    cnew = c.apply_space_motion(new_obstime=Time(epoch))
    star_coords = w.wcs_world2pix([cnew.ra.deg], [cnew.dec.deg], 0)

    xvalue = star_coords[0].ravel()
    yvalue = star_coords[1].ravel()
    flux = (searchresults['phot_g_mean_flux'] * u.mag).value

    ##### Error values
    cerr = SkyCoord(ra=searchresults['ra_error'],
                    dec=searchresults['dec_error'])

    xerrvalue = cerr.ra.value
    yerrvalue = cerr.dec.value

    xerrmask = np.nan_to_num(xerrvalue, nan=0.0, posinf=0.0, neginf=0.0)
    yerrmask = np.nan_to_num(yerrvalue, nan=0.0, posinf=0.0, neginf=0.0)
    xerrmask[xerrmask < 1.0] = 1.0
    yerrmask[yerrmask < 1.0] = 1.0
    ##### Error values less than 1.0 lead to incorrect values in photutils. Error values of 1.0 lead to no significiant differences in images compared to no error.

    ##### Create Table of results

    t = Table([flux, xvalue, yvalue, xerrmask, yerrmask],
              names=('flux', 'x_mean', 'y_mean', 'x_stddev', 'y_stddev'),
              dtype=('i8', 'i8', 'i8', 'i8', 'i8'))
    print('Table of stars is being generated as an image')
    zeroarr = make_gaussian_sources_image(shape, t)

    ##### Read noise

    read_noise = np.random.normal(scale=(3.92 / 1.829), size=shape)
    noise_image = make_noise_image(shape, distribution='poisson', mean=0.5)
    #####

    synth_image = zeroarr + noise_image
    #####
    ###### read_noise is disabled
    hdu = fits.PrimaryHDU(synth_image, header=hdr)
    hdul = fits.HDUList([hdu])
    hdul.writeto(image, overwrite=True)
    print('Synthetic GAIA DR2 image is saved as', image)
    return image
예제 #17
0
def WDGaiaRadius(ra,dec,teff,teff_err=None,searchradius=5.0,modelmass=0.6,
                 modelpath='AllModels/',A_G=0):
    """Estimate WD Radius from Gaia astrometry.
    
    Queries for Gaia data and distances from Bailer-Jones et al. (2018, ApJ, 156, 2).
    Scales Bergeron et al. DA (no DBs currently) cooling models 
    (http://www.astro.umontreal.ca/~bergeron/CoolingModels/)
    until the radius reproduces the Gaia magnitude at the parallactic distance.
    Corrects for extinction if coefficient A_G is provided in magnitudes, 
    following the prescription of Gentile-Fusillo et al. (2019, MNRAS, 482, 4570).
    Uses https://github.com/keatonb/BergeronToPandas to read in Bergeron models.
    If error on Teff given, includes contribution roughly in quadrature.
    Returns measurement and lower, upper bounds defined by Bailer-Jones et al. 
    confidence interval.
    
    ra, dec should be in decimal degrees
    teff,teff_err in Kelvin from spectroscopy
    searchradius is in arcseconds
    modelmass in solar units must match a file from the Bergeron models
                that is new enough to include synthetic Gaia magnitudes.
    """
    #First query Gaia sources
    coord = SkyCoord(ra=ra, dec=dec, unit=(u.degree, u.degree), frame='icrs')
    searchradius = u.Quantity(searchradius, u.arcsec)
    j = Gaia.cone_search_async(coord, searchradius)
    r = j.get_results()
    print("Gaia sources within {}: {}".format(searchradius,len(r)))
    if len(r) > 0:
        r.sort("dist")
        #Accept nearest
        sourceid = r["source_id"][0]
        Gmag = r["phot_g_mean_mag"][0]
        print("Nearest has Gaia G mag of {}.".format(Gmag))
        b = r["b"][0] #Galactic latitude in degrees
        #Extinction correction following Gentile-Fusillo et al. 2019
        parallax = r["parallax"][0]*1e-3 #arcsec
        extcorr = -A_G*(1. - np.exp(-np.sin(np.abs(b*np.pi/180)) / (200*parallax)))
        Gmag += extcorr
        print("Extinction correction of {} then applied to get G = {} mag.".format(extcorr,Gmag))
        
        
        #Then get Bailer-Jones distance
        v = Vizier(columns=['*'],
                column_filters={"Source":str(sourceid)}).get_catalogs('I/347')
        dist = np.array([v[0]["rest"][0],v[0]["b_rest"][0],v[0]["B_rest"][0]])
        print("Distance constraints from Bailer-Jones et al: {}".format(dist))
        
        #Referencing Bergeron cooling models
        modelfile = os.path.join(modelpath, "Table_Mass_{:.1f}".format(modelmass))
        print("Referencing Bergeron model file at "+modelfile)
        
        models = list(BergeronToPandas(modelfile).values())[0]
        
        #Constants
        G = 6.67259e-8 #cm3 g-1 s-2
        Msun = 1.99e33 #g
        Rsun = 6.96e10 #cm
        
        modelteff = models['Teff'].values
        modellogg = models['logg'].values
        modelradius = np.sqrt(G*modelmass*Msun/(10.**modellogg))/Rsun #solar radii
        
        modelGmag = models['G'].values
        
        #Define interpolation functions
        teff2radius = interp1d(modelteff,modelradius)
        teff2Gmag = interp1d(modelteff,modelGmag)
        
        distancemodulus = 5.*np.log10(dist)-5.
        
        #Start with values assuming along loaded model track
        trackradius = teff2radius(teff)
        trackGmag = teff2Gmag(teff)
        estGmag = trackGmag + distancemodulus 
        
        #Scale to measured magnitude
        remaining = estGmag - Gmag
        fluxratio = 2.512**remaining
        radiusratio = np.sqrt(fluxratio)
        gaiaradius = trackradius * radiusratio
        
        #Include effect of Teff_err if given
        if teff_err is not None:
            testteff = np.array([teff,teff+teff_err,teff-teff_err])
            trackradius = teff2radius(testteff)
            trackGmag = teff2Gmag(testteff)
            estGmag = trackGmag + distancemodulus[0]
            remaining = estGmag - Gmag
            fluxratio = 2.512**remaining
            radiusratio = np.sqrt(fluxratio)
            gr2 = trackradius * radiusratio
            #combine roughly in quadrature
            gaiaradius = gaiaradius[0] + np.sqrt((gaiaradius - gaiaradius[0])**2. + 
                                                 (gr2 - gr2[0])**2.)*np.array([1,-1,1])
        return gaiaradius
    else: #No Gaia results?
        print("Returning 'None's")
        return None,None,None
예제 #18
0
def make_gaia_image(skycoord,
                    fov,
                    sampling,
                    fwhm,
                    obsdate=dup.parse("2018 07 01 00:00:00 UTC"),
                    fn=os.path.join('.', 'pseudo_gaia.fits')):
    ''' 
   Given a coordinate, use the Gaia catalogue to create a mock image of the sky.
   
   Args:
      skycoord: the astropy SkyCoord of the center of the image
      fov: size of the image to create, in astropy.units
      sampling: pixel size of the image to create, in astropy.units
      fwhm: fwhm of the fake stars in the image, in astropy.units
      obsdate: date of the observation (to propagate the motion of the stars) as datetime.datetime object 
      fn: relative path + FITS filename
   Returns:
      The FITS filename
   '''

    # Ok, assemble an array of the suitable size
    nx = int(np.floor((fov / sampling).value))
    im = np.zeros((nx, nx))

    # Query GAIA
    print('   Querying GAIA to create a pseudo-image of the sky ...')
    # Make it a sync search, because I don't think I need more than 2000 targets ...
    # TODO: figure out why cone_search fails ... and fix it ! Swap to async for now...
    j = Gaia.cone_search_async(skycoord, fov, verbose=False)
    r = j.get_results()
    nstars = len(r)

    # TODO: well, what if I do need more than 2000 targets ?
    # Issue a warning for now ...
    if nstars == 2000:
        warnings.warn(
            ' Reached query limit of 2k stars. Gaia image will not be complete.'
        )

    # Create a very basic header for the FITS file
    hdr = fits.Header()
    hdr.set('CRPIX1', nx / 2, 'X reference pixel')
    hdr.set('CRPIX2', nx / 2, 'Y reference pixel')
    hdr.set('CRVAL1', skycoord.ra.deg, 'Reference longitude')
    hdr.set('CRVAL2', skycoord.dec.deg, 'Reference latitude')
    hdr.set('CTYPE1', 'RA---TAN', 'Coordinates -- projection')
    hdr.set('CTYPE2', 'DEC--TAN', 'Coordinates -- projection')
    hdr.set('CDELT1', -sampling.to(u.deg).value, 'X scale')  # mind the sign !
    hdr.set('CDELT2', sampling.to(u.deg).value, 'Y scale')
    hdr.set('RADESYS', 'ICRS', 'Coordinate system')
    hdr.set('EQUINOX', 2000.0, 'Epoch of the equinox')
    hdr['COMMENT'] = 'Artificial sky image reconstructed from the Gaia catalogue.'
    hdr['COMMENT'] = 'Number of stars: %i' % (nstars)
    hdr['COMMENT'] = 'FWHM: %i mas' % (int(fwhm.to(u.mas).value))
    hdr['COMMENT'] = 'Bandpass:    285.5-908 THz '
    hdr['COMMENT'] = 'Epoch: %s' % (obsdate.strftime('%Y-%h-%d %H:%M:%S UTC'))
    hdr['COMMENT'] = 'Created %s with fcmaker v%s' % (
        datetime.utcnow().strftime('%Y-%h-%d %H:%M:%S UTC'), fcm_v.__version__)
    hdr['COMMENT'] = 'See http://fpavogt.github.io/fcmaker for details.'

    # Save the empty FITS file for now
    hdu = fits.PrimaryHDU(im, header=hdr)
    hdul = fits.HDUList([hdu])
    hdul.writeto(fn, overwrite=True)

    # Re-extract the WCS info
    w = WCS(fn)

    # Prepare some variables
    x, y = np.meshgrid(np.arange(0, nx, 1), np.arange(0, nx, 1))
    sigma = (fwhm / sampling).value / (2 * np.sqrt(2 * np.log(2)))

    # For each star, add a Gaussian of the suitable size
    for s in range(nstars):
        # First, create a SkyCoord entry
        star = SkyCoord(
            ra=r['ra'][s],
            dec=r['dec'][s],
            obstime=Time(r['ref_epoch'][s], format='decimalyear'),
            frame='icrs',
            unit=(u.deg, u.deg),
            pm_ra_cosdec=r['pmra'][s] * u.mas / u.yr,
            pm_dec=r['pmdec'][s] * u.mas / u.yr,
            # I must specify a generic distance to the target,
            # if I want to later on propagate the proper motions
            distance=fcm_m.default_pm_d,
        )

        # Then, propagate the star at the time of the observation
        star_now = star.apply_space_motion(new_obstime=Time(obsdate))

        # Get the image coordinate of the star
        star_coords = w.wcs_world2pix([star_now.ra.deg], [star_now.dec.deg], 0)

        # The distance of all pixels to the star
        d = np.sqrt((x - star_coords[0])**2 + (y - star_coords[1])**2)

        # Add the star to the array ... scale it as a function of its flux
        im += r['phot_g_mean_flux'][s] * np.exp(-(
            (d)**2 / (2.0 * (fwhm / sampling).value**2)))

    # Save the final FITS file
    hdu = fits.PrimaryHDU(im, header=hdr)
    hdul = fits.HDUList([hdu])
    hdul.writeto(fn, overwrite=True)

    return fn
예제 #19
0
    context.prog_name = prog_name

##--------------------------------------------------------------------------##
##--------------------------------------------------------------------------##
##--------------------------------------------------------------------------##
## Search cone setup:
tgtcoo = coord.SkyCoord(ra=context.RA_deg,
                        dec=context.DE_deg,
                        unit=(uu.deg, uu.deg),
                        frame='icrs')
cone_radius = uu.Quantity(context.radius, uu.deg)

## Perform query:
sys.stderr.write("Running query ... \n")
tik = time.time()
qobj = Gaia.cone_search_async(tgtcoo, cone_radius)
hits = qobj.get_results()
tok = time.time()
sys.stderr.write("Query time: %.3f seconds.\n" % (tok - tik))

## Save results:
if context.output_file:
    sys.stderr.write("Saving to %s ... " % context.output_file)
    hits.write(context.output_file, format='ascii.csv')
    sys.stderr.write("done.\n")

######################################################################
# CHANGELOG (fetch_gaia_nearby.py):
#---------------------------------------------------------------------
#
#  2019-09-05:
예제 #20
0
def solve_wcs(input_file,
              telescope,
              sex_config_dir='./Config',
              static_mask=None,
              proc=None,
              log=None):
    #start time
    t_start = time.time()

    if log:
        log.info('Running solve_wcs version: ' + str(__version__))

    #import telescope parameter file
    global tel
    try:
        tel = importlib.import_module('tel_params.' + telescope)
    except ImportError:
        print('No such telescope file, please check that you have entered the'+\
            ' correct name or this telescope is available.''')
        sys.exit(-1)

    #get data and header info
    hdr = fits.open(input_file)
    data = hdr[tel.wcs_extension()].data
    data_y, data_x = np.shape(data)
    header = hdr[tel.wcs_extension()].header
    ra = header['CRVAL1']
    dec = header['CRVAL2']

    #run sextractor
    if log:
        log.info('Running SExtractor.')
    cat_name = input_file.replace('.fits', '.cat')
    table = run_sextractor(input_file,
                           cat_name,
                           tel,
                           sex_config_dir=sex_config_dir,
                           log=log)

    #mask and sort table
    if log:
        log.info('Masking sources and applying brightness cuts.')
    table = table[(table['FLAGS'] == 0)
                  & (table['EXT_NUMBER'] == tel.wcs_extension() + 1) &
                  (table['MAGERR_BEST'] != 99)]
    if static_mask:
        with fits.open(static_mask) as mask_hdu:
            stat_mask = mask_hdu[0].data
        table = table[(stat_mask[table['YWIN_IMAGE'].astype(int) - 1,
                                 table['XWIN_IMAGE'].astype(int) - 1] != 0)]
    table.sort('MAG_BEST')
    table = table[table['MAG_BEST'] < (np.median(table['MAG_BEST']) -
                                       np.std(table['MAG_BEST']))]
    if log:
        log.info('Total of %d usable stars' % len(table))

    #make quads using brightest stars
    if log:
        log.info('Making quads with the brightest 50 stars.')
    ind = list(itertools.combinations(np.arange(4), 2))
    stars, d, ds, ratios = make_quads(table['XWIN_IMAGE'],
                                      table['YWIN_IMAGE'],
                                      use=50)

    #query gaia
    if log:
        log.info(
            'Searching GAIA DR3 for stars within 10 arcmins of WCS in header.')
    Gaia.ROW_LIMIT = -1
    job = Gaia.cone_search_async(SkyCoord(ra * u.deg,
                                          dec * u.deg,
                                          frame='icrs'),
                                 10 * u.arcmin,
                                 table_name='gaiaedr3.gaia_source')
    gaiaorig = job.get_results()
    gaiaorig.sort('phot_g_mean_mag')
    if log:
        log.info(str(len(gaiaorig)) + ' GAIA stars found.')

    # Mask catalog so all data are inside nominal image
    if log:
        log.info('Applying image mask to GAIA sources.')
    mask = mask_catalog_for_wcs(gaiaorig, wcs.WCS(header), 1, data_x, data_y)
    gaia = gaiaorig[mask]
    if log:
        log.info(
            str(len(gaia)) + ' GAIA stars found within the image footprint.')

    #make quads using stars brigher than 20 mag
    if log:
        log.info(
            'Making quads with the brightest stars brighter than 20 mag and fainter than 14 mag.'
        )
    gaia = gaia[gaia['phot_g_mean_mag'] < 20]
    gaia = gaia[gaia['phot_g_mean_mag'] > 14]
    gaiastars, gaiad, gaiads, gaiaratios = make_quads(gaia['ra'],
                                                      gaia['dec'],
                                                      use=50,
                                                      sky_coords=True)

    #match quads
    if log:
        log.info('Matching quads between the detected and cataloged stars.')
    try:
        starsx, starsy, gaiastarsra, gaiastarsdec = match_quads(
            stars,
            gaiastars,
            d,
            gaiad,
            ds,
            gaiads,
            ratios,
            gaiaratios,
            sky_coords=True)
        if log:
            log.info('Found ' + str(len(starsx)) + ' unique star matches.')

        #calculate inital transformation
        if log:
            log.info(
                'Calculating the initial transformation between the matched stars.'
            )
        gaiax, gaiay = wcs.utils.skycoord_to_pixel(
            SkyCoord(gaiastarsra, gaiastarsdec, unit='deg'), wcs.WCS(header),
            1)
        tform = tf.estimate_transform('euclidean', np.c_[starsx, starsy],
                                      np.c_[gaiax, gaiay])

        #apply initial transformation to header
        if log:
            log.info(
                'Applying the initial transformation to the existing WCS in the header.'
            )
        header_new = apply_wcs_transformation(header, tform)
    except:
        if log:
            log.error('Unique star matching failed.')
        crpix1, crpix2, cd11, cd12, cd21, cd22 = wcs_keyword = tel.WCS_keywords(
        )
        header['CD1_1'] = header[cd11]
        header['CD1_2'] = header[cd12]
        header['CD2_1'] = header[cd21]
        header['CD2_2'] = header[cd22]
        header['CTYPE1'] = 'RA---TAN'
        header['CTYPE2'] = 'DEC--TAN'
        old_keywords = tel.WCS_keywords_old()
        for old in old_keywords:
            try:
                del header[old]
            except:
                pass
        header_new = header

    #matching all stars to catalog
    if log:
        log.info('Matching all stars to the catalog.')
    stars_ra, stars_dec = (wcs.WCS(header_new)).all_pix2world(
        table['XWIN_IMAGE'], table['YWIN_IMAGE'], 1)
    stars_radec = SkyCoord(stars_ra * u.deg, stars_dec * u.deg)
    gaia_radec = SkyCoord(gaia['ra'], gaia['dec'], unit='deg')
    idx, d2, d3 = gaia_radec.match_to_catalog_sky(stars_radec)
    match = d2 < 5.0 * u.arcsec
    idx = idx[match]
    starx_match = [table['XWIN_IMAGE'][x] for x in idx]
    stary_match = [table['YWIN_IMAGE'][x] for x in idx]
    gaia_radec = SkyCoord(gaia[match]['ra'], gaia[match]['dec'], unit='deg')
    gaiax_match, gaiay_match = wcs.utils.skycoord_to_pixel(
        gaia_radec, wcs.WCS(header_new), 1)
    if log:
        log.info('Found ' + str(len(starx_match)) + ' star matches within 5".')

    #calculate and apply full transformation
    if log:
        log.info(
            'Calculating the full transformation between the matched stars.')
    tform = tf.estimate_transform('euclidean', np.c_[starx_match, stary_match],
                                  np.c_[gaiax_match, gaiay_match])
    if log:
        log.info(
            'Applying the full transformation to the existing WCS in the header.'
        )
    header_new['CRPIX1'] = header_new['CRPIX1'] - tform.translation[0]
    header_new['CRPIX2'] = header_new['CRPIX2'] - tform.translation[1]
    cd = np.array([
        header_new['CD1_1'], header_new['CD1_2'], header_new['CD2_1'],
        header_new['CD2_2']
    ]).reshape(2, 2)
    cd_matrix = tf.EuclideanTransform(rotation=tform.rotation)
    cd_transformed = tf.warp(cd, cd_matrix)
    header_new['CD1_1'] = cd_transformed[0][0]
    header_new['CD1_2'] = cd_transformed[0][1]
    header_new['CD2_1'] = cd_transformed[1][0]
    header_new['CD2_2'] = cd_transformed[1][1]
    header_new['WCS_REF'] = ('GAIA-DR2',
                             'Reference catalog for astrometric solution.')
    header_new['WCS_NUM'] = (len(starx_match),
                             'Number of stars used for astrometric solution.')

    #calculate polynomial distortion
    if log:
        log.info(
            'Calculating and applying the higher order polynomial distortion.')
    header_dist = apply_wcs_distortion(header_new, starx_match, stary_match,
                                       gaia[match]['ra'], gaia[match]['dec'])

    #calculate error. This error now uses dvrms() instead of np.median.
    if log:
        log.info('Calculating the rms on the astrometry.')
    stars_ra, stars_dec = (wcs.WCS(header_dist)).all_pix2world(
        starx_match, stary_match, 1)
    stars_radec = SkyCoord(stars_ra * u.deg, stars_dec * u.deg)
    error = calculate_error(stars_radec, gaia_radec, header_dist)

    #write out new fits
    fits.writeto(input_file.replace('.fits', '_wcs.fits'),
                 data,
                 header_dist,
                 overwrite=True)

    #end and run time
    t_end = time.time()
    if log:
        log.info('Solve_wcs ran in ' + str(t_end - t_start) + ' sec')
    else:
        print('Solve_wcs ran in ' + str(t_end - t_start) + ' sec')

    return 'Median rms on astrometry is %.3f arcsec.' % error
예제 #21
0
def draw_fc(fc_params, bk_image=None, bk_lam=None, do_pdf=False, do_png=False):
    ''' 
   The finding chart master plotting function.
   
   Args:
      fc_params: a dictionnary containing the OB parameters
      bk_image: the background image as string, either a SkyView entry, or local filename
      bk_lam: the wavelength of the chart as a string
      do_pdf (bool): save a pdf file, in addition to jpg
      do_png (bool): save a png file, in addition to jpg
   Returns:
      The finding chart filename as a string
   '''

    # Load all the fields dictionaries
    fields = fcm_id.get_fields_dict(fc_params)

    # Get the radius and center of the charts
    (left_radius, right_radius) = fcm_id.get_chart_radius(fc_params)
    (left_center, right_center) = fcm_id.get_chart_center(fc_params)

    # Get the background image in place
    (fn_bk_image_L, survey_L, bk_lam_L) = get_bk_image(bk_image, bk_lam,
                                                       left_center,
                                                       left_radius, fc_params)

    # If this is not the DSS2 Red, then download this as well for the right-hand-side plot
    if not (survey_L == 'DSS2 Red'):
        (fn_bk_image_R, survey_R,
         bk_lam_R) = get_bk_image('DSS2 Red', None, right_center, right_radius,
                                  fc_params)
    else:
        (fn_bk_image_R, survey_R, bk_lam_R) = copy.deepcopy(
            (fn_bk_image_L, survey_L, bk_lam_L))

    # Start the plotting
    plt.close(1)
    fig1 = plt.figure(
        1,
        figsize=(14.17, 7))  #14.17 inches, at 50% = 1 full page plot in A&A.

    ax1 = aplpy.FITSFigure(fn_bk_image_L,
                           figure=fig1,
                           north=fcm_m.set_North,
                           subplot=[0.12, 0.12, 0.35, 0.76])
    ax1.show_grayscale(invert=True,
                       stretch='linear',
                       pmin=fcm_id.get_pmin(survey_L),
                       pmax=99.9)

    ax2 = aplpy.FITSFigure(fn_bk_image_R,
                           figure=fig1,
                           north=fcm_m.set_North,
                           subplot=[0.59, 0.12, 0.38, 0.8])
    ax2.show_grayscale(invert=True,
                       stretch='linear',
                       pmin=fcm_id.get_pmin(survey_R))

    ax1.recenter(left_center.ra, left_center.dec, radius=left_radius / 3600.)
    ax2.recenter(right_center.ra,
                 right_center.dec,
                 radius=right_radius / 3600.)

    # I will be adding stuff to the left-hand-side plot ... start collecting them
    ax1_legend_items = []

    # Do I have the epoch of observation for the background image ?
    '''
   try:
      bk_obsdate = fits.getval(fn_bk_image, 'DATE-OBS')
      
      # If not specified, assume UTC time zone for bk image   
      if bk_obsdate.tzinfo is None:
      #   #warnings.warn(' "--obsdate" timezone not specified. Assuming UTC.')
         bk_obsdate = bk_obsdate.replace(tzinfo=pytz.utc)
      
      nowm_time = Time(bk_obsdate)
      pm_track_time = (fcm_obsdate - bk_obsdate).total_seconds()*u.s
      
   except:
      # If not, just shows the default length set in fcmaker_metadata
      nowm_time = Time(fcm_m.obsdate) - fcm_m.pm_track_time
      pm_track_time = fcm_m.pm_track_time
   '''

    # Just keep things simple. Same lookback time for all charts.
    nowm_time = Time(fcm_m.obsdate) - fcm_m.pm_track_time
    #pm_track_time = fcm_m.pm_track_time

    # If yes, then let's show where are the fastest stars moved from/to.
    #if do_GAIA_pm and (fcm_m.min_abs_GAIA_pm >=0):
    if (fcm_m.min_abs_GAIA_pm >= 0):

        # Query GAIA
        print(
            '   Querying GAIA DR2 to look for high proper motion stars in the area ...'
        )

        # Make it a sync search, because I don't think I need more than 2000 targets ...
        # 2020-04: for some reason the sync search fails ... run an async one for now.
        j = Gaia.cone_search_async(left_center,
                                   right_radius * u.arcsec,
                                   verbose=False)
        r = j.get_results()

        selected = np.sqrt(r['pmra']**2 + r['pmdec']**2
                           ) * u.mas / u.yr > fcm_m.min_abs_GAIA_pm

        # Show the fastest stars
        past_tracks = []
        future_tracks = []

        # Need to propagate their coords to the fc epoch and the obstime
        for s in range(len(r['ra'][selected])):

            star = SkyCoord(
                ra=r['ra'][selected][s],
                dec=r['dec'][selected][s],
                obstime=Time(r['ref_epoch'][selected][s],
                             format='decimalyear'),
                frame='icrs',
                unit=(u.deg, u.deg),
                pm_ra_cosdec=r['pmra'][selected][s] * u.mas / u.yr,
                pm_dec=r['pmdec'][selected][s] * u.mas / u.yr,
                # I must specify a generic distance to the target,
                # if I want to later on propagate the proper motions
                distance=fcm_m.default_pm_d,
            )

            now = star.apply_space_motion(new_obstime=Time(fcm_m.obsdate))
            nowm = star.apply_space_motion(new_obstime=nowm_time)

            past_tracks += [
                np.array([[nowm.ra.deg, now.ra.deg],
                          [nowm.dec.deg, now.dec.deg]])
            ]

            for ax in [ax1, ax2]:
                ax.show_markers([now.ra.deg], [now.dec.deg],
                                marker='.',
                                color='crimson',
                                facecolor='crimson',
                                edgecolor='crimson')

        #if len(r['ra'][selected])>0:
        #   # Prepare a dedicated legend entry
        #   ax1_legend_items += [mlines.Line2D([], [],color='crimson',
        #                         markerfacecolor='crimson',
        #                         markeredgecolor='crimson',
        #                         linestyle='-',
        #                         linewidth=0.75,
        #                         marker='.',
        #                         #markersize=10,
        #                         label='PM* (track$=-$%.1f yr)' % (pm_track_time.to(u.yr).value)) ]
        for ax in [ax1, ax2]:
            ax.show_lines(past_tracks,
                          color='crimson',
                          linewidth=0.75,
                          linestyle='-')

    # Query UCAC2 via Vizier over the finding chart area, to look for suitable Guide Stars
    print('   Querying UCAC2 via Vizier to look for possible Guide Stars ...')
    Vizier.ROW_LIMIT = 10000
    gs_table = Vizier.query_region(
        right_center,
        radius=right_radius * u.arcsec,
        inner_radius=fcm_id.get_inner_GS_search(fc_params) * u.arcsec,
        catalog="UCAC2")
    gs_table = gs_table[gs_table.keys()[0]]

    # Turn the table into a list of SkyCoord, that I can clean as I go.
    # Only select guide stars in the nominal GS mag range
    gs_list = [
        SkyCoord(
            ra=line['RAJ2000'],
            dec=line['DEJ2000'],
            obstime=Time('J2000'),
            equinox='J2000',
            frame='icrs',
            unit=(u.deg, u.deg),
            pm_ra_cosdec=line['pmRA'] / 1000. * u.mas / u.yr,
            pm_dec=line['pmDE'] / 1000. * u.mas / u.yr,
            # Assume a fixed distance, so that I can then propagate proper motions
            distance=100. *
            u.pc).apply_space_motion(new_obstime=Time(fcm_m.obsdate))
        for line in gs_table
        if fcm_m.gs_mag[0] <= line['UCmag'] <= fcm_m.gs_mag[1]
    ]

    # Here, I will show all the ephemeris points I have prepared, ahead of the
    # observations (If I have any)

    if len(fc_params['ephem_points_past']) > 0:
        ax1.show_markers(
            [item.ra.deg for item in fc_params['ephem_points_past']],
            [item.dec.deg for item in fc_params['ephem_points_past']],
            marker='*',
            color='crimson',
            s=100,
            facecolor='none',
            edgecolor='crimson')

        # Prepare a dedicated legend entry
        ax1_legend_items += [
            mlines.Line2D(
                [],
                [],
                color='crimson',
                markerfacecolor='none',
                markeredgecolor='crimson',
                linestyle='',
                #linewidth=0.75,
                marker='*',
                #markersize=10,
                label='Target ($\Delta T=-%.0f$ min)' %
                (fc_params['ephem_past_delta'].total_seconds() / 60.))
        ]

    if len(fc_params['ephem_points_future']) > 0:
        ax1.show_markers(
            [item.ra.deg for item in fc_params['ephem_points_future']],
            [item.dec.deg for item in fc_params['ephem_points_future']],
            marker='*',
            color='crimson',
            s=100,
            facecolor='crimson',
            edgecolor='crimson')

        # Prepare a dedicated legend entry
        ax1_legend_items += [
            mlines.Line2D(
                [],
                [],
                color='crimson',
                markerfacecolor='crimson',
                markeredgecolor='crimson',
                linestyle='',
                #linewidth=0.75,
                marker='*',
                #markersize=10,
                label='Target ($\Delta T=+%.0f$ min)' %
                (fc_params['ephem_future_delta'].total_seconds() / 60.))
        ]

    # Show the observation footprint
    for f in fields:

        # Call the function that will plot all the important stuff for this field.
        fcm_id.plot_field(ax1, ax2, fc_params, fields[f])

        # Keep all the possible guide stars in the area.
        gs_list = [
            star for star in gs_list
            if (fields[f][2].separation(star) >
                (fcm_id.get_inner_GS_search(fc_params) / 3600. * u.deg)) and (
                    fields[f][2].separation(star) <
                    (fcm_id.get_GS_outer_radius(fc_params) / 3600. * u.deg))
        ]

    # Show all the suitable Guide Star in the area
    if len(gs_list) > 0:
        ax2.show_markers([np.array(star.ra) for star in gs_list],
                         [np.array(star.dec) for star in gs_list],
                         marker='o',
                         edgecolor='crimson',
                         s=50,
                         linewidth=1.0)
    else:
        warnings.warn('Watch out ... no suitable Guide Star found in UCAC2 !')

    # Add orientation arrows to the large view plot
    add_orient(ax2,
               right_center,
               radius=(right_radius * 0.82) * u.arcsec,
               arrow_width=(right_radius * 0.82) / 4.5 * u.arcsec,
               usetex=fcm_m.fcm_usetex)
    add_orient(ax1,
               left_center,
               radius=(left_radius * 0.82) * u.arcsec,
               arrow_width=(left_radius * 0.82) / 4.5 * u.arcsec,
               usetex=fcm_m.fcm_usetex)

    # Add a scale bar
    (scl, scll) = fcm_id.get_scalebar(fc_params['inst'],
                                      ins_mode=fc_params['ins_mode'])

    ax1.add_scalebar(scl)  # Length in degrees
    ax1.scalebar.show(scl,
                      label=scll,
                      corner='bottom left',
                      color='k',
                      frame=1)
    ax1.scalebar.set_font_size(12)

    scl2 = np.floor(right_radius / 60 / 6) / 60.
    scll2 = r'%.0f$^{\prime}$' % (scl2 * 60)
    ax2.add_scalebar(scl2)
    ax2.scalebar.show(scl2,
                      label=scll2,
                      corner='bottom left',
                      color='k',
                      frame=1)
    ax2.scalebar.set_font_size(12)

    for ax in [ax1, ax2]:
        ax.scalebar.set_linewidth(2)

    # Fine tune things a bit further, just because I can ...
    for ax in [ax1, ax2]:
        ax.tick_labels.set_xformat('hh:mm:ss')
        ax.axis_labels.set_xpad(10)
        ax.ticks.set_linewidth(1.5)
        ax.ticks.set_length(10)
        ax.ticks.set_color('k')
        ax.axis_labels.set_xtext('R.A. [J2000]')

    ax1.axis_labels.set_ytext('Dec. [J2000]')
    #ax1.axis_labels.set_ypad(-10)
    ax2.axis_labels.set_ytext(' ')

    # Add the required OB information to comply with ESO requirements ...
    # ... and make the life of the night astronomer a lot easier !
    ax1.add_label(0.0,
                  1.11,
                  'Run ID: ' + fc_params['prog_id'] + ' | ' + fc_params['pi'],
                  relative=True,
                  horizontalalignment='left',
                  size=14)

    # Fix some bugs for anyone not using LaTeX ... sigh ...
    if fcm_m.fcm_usetex:
        lab = fc_params['ob_name'].replace('_', '\_')
    else:
        lab = fc_params['ob_name']

    ax1.add_label(0.0,
                  1.06,
                  'OB: %i | %s' % (fc_params['ob_id'], lab),
                  relative=True,
                  horizontalalignment='left',
                  size=14)
    #ax1.add_label(0.0,1.08, r'$\lambda_{fc}$: %s (%s)' % (bk_lam_L, survey_L), relative=True,
    #              horizontalalignment='left')

    # Display the Wavelength of the plots
    ax1.add_label(0.02,
                  0.965,
                  r'%s (%s)' % (bk_lam_L, survey_L),
                  relative=True,
                  fontsize=12,
                  horizontalalignment='left',
                  verticalalignment='center',
                  bbox=dict(edgecolor='w', facecolor='w', alpha=0.85))
    ax2.add_label(0.02,
                  0.965,
                  r'%s (%s)' % (bk_lam_R, survey_R),
                  relative=True,
                  fontsize=12,
                  horizontalalignment='left',
                  verticalalignment='center',
                  bbox=dict(edgecolor='w', facecolor='w', alpha=0.85))

    # Add a legend (if warranted) for the left plot
    if len(ax1_legend_items) > 0:
        ax1.ax.legend(
            handles=ax1_legend_items,
            bbox_to_anchor=(-0.03, 0.82, 0.4, .1),  #loc='lower right',
            ncol=1,  #mode="expand", 
            borderaxespad=0.,
            fontsize=10,
            borderpad=0.3,
            handletextpad=0.,
            handlelength=2.0)

    # Start keeping track of any tags I need to show
    tag_string = r' '

    # Show the obsdate
    ax1.add_label(1.0,
                  1.02,
                  r'Date: ' +
                  datetime.strftime(fcm_m.obsdate, '%Y-%m-%d %H:%M %Z'),
                  relative=True,
                  color='k',
                  horizontalalignment='right',
                  fontsize=10)

    # Show the OB tags
    if 'moving_target' in fc_params['tags']:
        tag_string += '$\leadsto$ '

    if 'parallactic_angle' in fc_params['tags']:
        tag_string += '$\measuredangle$ '

    if len(tag_string) > 1:  # only show the tag if it has a non-zero length
        ax1.add_label(
            -0.18,
            1.08,
            tag_string,
            relative=True,
            color='k',
            horizontalalignment='center',
            verticalalignment='center',
            fontsize=30,
            bbox=dict(edgecolor='k',
                      facecolor='lightsalmon',
                      alpha=1,
                      linewidth=1,
                      boxstyle="sawtooth,pad=0.2,tooth_size=0.075"),
        )

    # Finally include the version of fcmaker in there
    ax1.add_label(1.01,
                  0.00,
                  r'Created with fcmaker v%s' % (fcm_v.__version__),
                  relative=True,
                  horizontalalignment='left',
                  verticalalignment='bottom',
                  fontsize=10,
                  rotation=90)

    # Save it all, both jpg for upload to p2, and pdf for nice quality.
    fn_out = os.path.join(
        fcm_m.plot_loc, fc_params['ob_name'].replace(' ', '_') + '_' +
        survey_L.replace(' ', '-'))

    fig1.savefig(fn_out + '.jpg')
    if do_pdf:
        fig1.savefig(fn_out + '.pdf')
    if do_png:
        fig1.savefig(fn_out + '.png')

    plt.close()

    return fn_out + '.jpg'
예제 #22
0
def querycat_gaia(ralist=None, declist=None, cone_search=False,
                  width=10.0, height=10.0, radius=5.0, dr2=False,
                test=False, debug=False):
    """


    """

    import time

    from astropy.table import Table, vstack

    import astropy.units as u
    from astropy.coordinates import SkyCoord
    from astroquery.gaia import Gaia

    if dr2:
        help(Gaia)
        gaiadr2_table = Gaia.load_table('gaiadr2.gaia_source')
        for column in (gaiadr1_table.get_columns()):
            print(column.get_name())

    if debug:
        help(Gaia)

    width = u.Quantity(width/3600.0, u.degree)
    height = u.Quantity(height/3600.0, u.degree)
    radius = u.Quantity(radius/3600.0, u.degree)


    if test is True:
        ralist = [180.0]
        declist = [0.0]

        width = u.Quantity(30.0, u.arcsec)
        height = u.Quantity(30.0, u.arcsec)
        radius = u.Quantity(15.0, u.arcsec)

    result_nrows = 0
    for isource, (ra, dec) in enumerate(zip(ralist, declist)):

        coord = SkyCoord(ra=ra, dec=dec,
                         unit=(u.degree, u.degree),
                         frame='icrs')

        t0 = time.time()
        if not cone_search:
            result = Gaia.query_object_async(coordinate=coord,
                                             width=width, height=height)
            # help(result)
            if debug:
                result.pprint()
                result.info('stats')

        if cone_search:
            job = Gaia.cone_search_async(coord, radius)
            # help(job)
            result = job.get_results()

        print('Number of rows:', len(result))
        print('Elapsed time(secs):',time.time() - t0)

        if debug:
           help(result)
           result.pprint()
           result.info('stats')


        result_nrows = result_nrows + len(result)
        if isource == 0:
            result_all = result
        if isource > 0:
           result_all = vstack([result_all, result])

#def fix_vot_object():
    table = result_all
    print('icol, format, dtype')
    # help(table)
    # help(table.columns)
    for (icol, column) in enumerate(table.columns):
        print(icol, table.columns[icol].name,
              table.columns[icol].format,
              table.columns[icol].dtype)
        # convert the columns for dtype = object which is not
        # supported by FITs to bool
        if table.columns[icol].dtype == 'object':
            colname = table.columns[icol].name
            NewColumn = Table.Column(table[colname].data, dtype='bool')
            table.replace_column(colname, NewColumn)
    print()


    result_all = table

    print('Number of Gaia sources returned:', result_nrows, len(result_all))

    return result_all
예제 #23
0
    from cleaner import cleaner
    omask = cleaner(lkf.time, lkf.flux)
    ntime = lkf.time.value[~omask]
    nflux = lkf.flux.value[~omask]
    nflux_err = lkf.flux_err.value[~omask]

    lkf = TessLightCurve(time=ntime, flux=nflux, flux_err=nflux_err)
   
    
#Gaia sources and dilution factor
if args.gaia:
    from astroquery.gaia import Gaia
    Gaia.ROW_LIMIT = -1

    gaiawh = u.Quantity(21*args.size*np.sqrt(2)/2, u.arcsec)
    gaiar  = Gaia.cone_search_async(coord, gaiawh).get_results()
    #gaiar  = Gaia.query_object_async(coord, width=gaiawh, height=gaiawh)

    gma = gaiar['phot_rp_mean_mag'] < args.maxgaiamag*u.mag
    gra, gdec = gaiar['ra'][gma], gaiar['dec'][gma]
    grpmag    = gaiar['phot_rp_mean_mag'][gma]
    gsep      = gaiar['dist'][gma]*3600
    gaiar     = gaiar[gma]

    #Come back to origin (0,0) for a while
    goffsetx = column if args.folder is not None else 0
    goffsety = row if args.folder is not None else 0

    go = 0 if args.folder is None else 1
    gx, gy = w.all_world2pix(gra, gdec, go) + (np.ones(2)*.5)[:,None]
예제 #24
0
def do_gaia_match(df):

    # first, crossmatch against SIMBAD to get the coordinates

    starnames = nparr(df['star'])
    for ix, s in enumerate(starnames):
        # manual string subbing for simbad query
        if 'Qatar' in s:
            starnames[ix] = s.replace('-', ' ')
        if s == 'WASP-70A':
            starnames[ix] = s.rstrip('A')

    ras, decs = [], []
    print('running SIMBAD query...')
    for ix, starname in enumerate(starnames):
        print(ix, starname)
        result = Simbad.query_object(starname)
        if len(result) != 1:
            raise AssertionError
        ras.append(result['RA'].tolist()[0])
        decs.append(result['DEC'].tolist()[0])
    ras = np.array(ras)
    decs = np.array(decs)

    coords = SkyCoord(ras, decs, frame='icrs', unit=(u.hourangle, u.deg))

    # then, crossmatch against Gaia to get the absolute G mags

    radius = units.Quantity(2, units.arcsec)

    sep, gaia_id, parallax, gmag, dr2_teff, dr2_radius, dr2_lum, distance = (
        [], [], [], [], [], [], [], [])
    print('running Gaia query...')
    for ix, sysname, coord in zip(range(len(coords)), nparr(df['star']),
                                  coords):
        print('{:d}/{:d} --- {:s}'.format(ix, len(coords), sysname))
        j = Gaia.cone_search_async(coord, radius)
        r = j.get_results()

        if len(r) == 0:
            print('\tno match, skipping')
            for l in [
                    sep, gaia_id, parallax, gmag, dr2_teff, dr2_radius,
                    dr2_lum, distance
            ]:
                l.append(np.nan)
            continue

        if len(r) > 1:
            print('\tmatched {:d} within 2arcsec, skipping'.format(len(r)))
            for l in [
                    sep, gaia_id, parallax, gmag, dr2_teff, dr2_radius,
                    dr2_lum, distance
            ]:
                l.append(np.nan)
            continue

        sep.append(float((r['dist'] * units.deg).to(units.arcsec).value))
        gaia_id.append(int(r['source_id']))
        plx = float(r['parallax'] * 1e-3)
        parallax.append(plx)
        distance.append(1 / plx)
        gmag.append(float(r['phot_g_mean_mag']))
        dr2_teff.append(float(r['teff_val']))
        dr2_radius.append(float(r['radius_val']))
        dr2_lum.append(float(r['lum_val']))

    sep, gaia_id, parallax, gmag, dr2_teff, dr2_radius, dr2_lum, distance = (
        nparr(sep), nparr(gaia_id), nparr(parallax), nparr(gmag),
        nparr(dr2_teff), nparr(dr2_radius), nparr(dr2_lum), nparr(distance))

    df['sep'] = sep
    df['gaia_id'] = gaia_id
    df['parallax'] = parallax
    df['gmag'] = gmag
    df['dr2_teff'] = dr2_teff
    df['dr2_radius'] = dr2_radius
    df['dr2_lum'] = dr2_lum
    df['distance'] = distance

    savname = '../data/bonomo_HJs_plus_DR2.csv'
    df.to_csv(savname, index=False)
    print('made {}'.format(savname))