コード例 #1
0
    def conesearch(self, ra, dec, radius, **kwargs):
        ## ToDo: rewrite to use Gaia Archive, not tap service.  Need to ditch distance param and just use parallax
        # input parameters in degrees:
        ra_ = ra.to(u.degree); dec_= dec.to(u.degree); rad_=radius.to(u.degree)

        maxrec = kwargs.get('maxrec', 20000)

        columnlist = self._get_col_list() + ', gd.r_est'
        dbsource = '\n\t'.join(['\nFROM gaiadr2_complements.geometric_distance gd',
                    'INNER JOIN gaiadr2.gaia_source gs using (source_id) '])

        constraints =  '\n\t'.join(['\nWHERE ', 
                'CONTAINS(POINT(\'\', gs.ra, gs.dec), ',
                '\tCIRCLE(\'\', {ra}, {dec}, {rad})) = 1 '.format(ra=ra_.value, dec=dec_.value, rad=rad_.value)])

        if self.source_constraints is not None:
            constraints = constraints + ' AND '+ self.source_constraints

        self.tap_query_string = 'SELECT \n\t\t'+ columnlist + dbsource + constraints
        
        tap_service = TAPService(self.tap_service_url)
        tap_results = tap_service.search(self.tap_query_string, maxrec=maxrec)

        self.objs = tap_results.to_table().to_pandas()
        self.objs.set_index('source_id', inplace=True)
コード例 #2
0
 def from_source_idlist(self, source_idlist, source_idcol=None, filters=False):
     #xml-ify the source_idlist to a file
     if isinstance(source_idlist, Table):
         #guess which column contains the source ids
         if source_idcol is None:
             if 'source_id' in source_idlist.colnames:
                 sidcol = 'source_id'
             elif 'source' in source_idlist.colnames:
                 sidcol = 'source'
             else:
                 raise ValueError('no column to use as source_id')
         else:
             if source_idcol not in source_idlist.colnames:
                 raise ValueError(f'invalid column specified as source id column: {source_idcol}')
             sidcol = source_idcol
             
         tbl = source_idlist
     elif isinstance(source_idlist, np.ndarray) or isinstance(source_idlist, list):
         sidcol = 'source_id'
         tbl = Table({sidcol:source_idlist})
     else:
         raise ValueError(f'invalid source_idlist type: {type(source_idlist)}')
     xml_path = 'source_idlist.xml'
     tbl.write(xml_path, table_id='source_idlist', format='votable', overwrite=True)
     
     #build the query:
     col_list = self._get_col_list() + ', gd.r_est'
     
     dbsource =  ''.join([' FROM tap_upload.source_idlist sidl',
                         f' LEFT JOIN gaiadr2.gaia_source gs ON gs.source_id = sidl.{sidcol}',
                         f' LEFT JOIN gaiadr2_complements.geometric_distance gd on gs.source_id = gd.source_id' ])
     
     query_str = f'SELECT sidl.{sidcol} as "source", '+col_list+dbsource
     if filters:
         query_str = query_str + ' WHERE '+ self.source_constraints
     self.tap_query_string = query_str
     
     #fetch the data
     #job = Gaia.launch_job_async(query=query_str, upload_resource=xml_path,upload_table_name='source_idlist')
     #self.objs = job.get_results().to_pandas()
     
     #fetch data via tap query
     tap_service = TAPService(self.tap_service_url)
     tap_results = tap_service.search(self.tap_query_string, maxrec=len(tbl),uploads={'source_idlist':tbl})
     self.objs = tap_results.to_table().to_pandas()
     
     
     self.objs.set_index('source', inplace=True)
コード例 #3
0
from pyvo.dal import TAPService
import astropy
from astropy.table import Table, vstack
import sys

tap_service = TAPService("http://dc.g-vo.org/tap")
tap_results = tap_service.search("SELECT TOP 10 * FROM ivoa.obscore")
print(tap_results)
コード例 #4
0
ファイル: tapdatabase.py プロジェクト: lucilecoutouly/nenupy
class ObsDatabase(object):
    """ Class to access NenuFAR BST TAP service.
    """
    def __init__(self):
        self.service = TAPService(nancay_tap)
        log.info(f'TAP service {nancay_tap} accessed.')
        self.meta_names = [
            'target_name', 'obs_creator_did', 's_ra', 's_dec', 't_min',
            't_max', 'em_min', 'em_max'
        ]
        self._conditions = {
            'time': '',
            'freq': '',
            'pos': '',
        }
        self.time_range = [None, None]
        self.freq_range = [None, None]
        self.fov_radius = 180 * u.deg
        self.fov_center = None

    # --------------------------------------------------------- #
    # --------------------- Getter/Setter --------------------- #
    @property
    def meta_names(self):
        """ Column names (observation properties) to return using
            :meth:`~nenupy.observation.tapdatabase.ObsDatabase.search`.

            :setter: `list` of column names.

            :getter: Properties to query.
            
            :type: `str`

            :seealso:
                `Database description
                <http://vogate.obs-nancay.fr/__system__/dc_tables/show/tableinfo/nenufar.bst>`_
        
        """
        return ', '.join(self._meta_names)

    @meta_names.setter
    def meta_names(self, m):
        if not isinstance(m, list):
            raise TypeError('meta_names must be a list')
        unknown_mask = ~np.isin(m, colnames)
        if unknown_mask.any():
            unknown = np.array(m)[unknown_mask]
            raise ValueError('Unknown meta_names: {}, available: {}'.format(
                unknown, colnames))
        self._meta_names = m
        return

    @property
    def time_range(self):
        """ Time range selection for the ADQL query using
            :meth:`~nenupy.observation.tapdatabase.ObsDatabase.search`.
            Default is ``[None, None]`` which means that no
            condition based on observation time will be applied.

            :setter: Length-2 list of ``[start, stop]``. ``start``
                and ``stop`` may be passed as :class:`~astropy.time.Time`
                instances or as ISO/ISOT `str`.

            :getter: ``[start, stop]`` list.
            
            :type: `list`
        """
        return self._time_range

    @time_range.setter
    def time_range(self, t):
        if t == [None, None]:
            self._conditions['time'] = ''
            self._time_range = t
            return
        if not isinstance(t, list):
            raise TypeError('time_range must be a list')
        if not len(t) == 2:
            raise ValueError('time_range must be of length 2')
        if not all([isinstance(ti, Time) for ti in t]):
            t = [Time(ti) for ti in t]
        self._conditions['time'] = f'(t_min >= {t[0].mjd} '\
            f'AND t_max <= {t[1].mjd})'
        log.info(f'time_range set to {t}.')
        self._time_range = t
        return

    @property
    def freq_range(self):
        """ Frequency range selection for the ADQL query using
            :meth:`~nenupy.observation.tapdatabase.ObsDatabase.search`.
            Default is ``[None, None]`` which means that no
            condition based on observation frequencies will be applied.

            :setter: Length-2 list of ``[fmin, fmax]``. ``fmin``
                and ``fmax`` may be passed as :class:`~astropy.units.Quantity`
                instances or as `float` (assumed to be expressed
                in MHz).

            :getter: ``[fmin, fmax]`` list.
            
            :type: `list`
        """
        return self._freq_range

    @freq_range.setter
    def freq_range(self, f):
        if f == [None, None]:
            self._conditions['freq'] = ''
            self._freq_range = f
            return
        if not isinstance(f, list):
            raise TypeError('freq_range must be a list')
        if not len(f) == 2:
            raise ValueError('freq_range must be of length 2')
        if not all([isinstance(fi, u.Quantity) for fi in f]):
            f = [fi * u.MHz for fi in f]
        lmax = wavelength(f[0]).to(u.m).value
        lmin = wavelength(f[1]).to(u.m).value
        self._conditions['freq'] = f'(em_min >= {lmin} AND '\
            f'em_max <= {lmax})'
        log.info(f'freq_range set to {f}.')
        self._freq_range = f
        return

    @property
    def fov_radius(self):
        """ Radius of the query, in combination with the query
            center :attr:`~nenupy.observation.tapdatabase.ObsDatabase.fov_center`.
    
            :setter: Radius (in degrees if no unit is provided). Default is ``180 deg``.

            :getter: Radius in degrees.
            
            :type: `float` or :class:`~astropy.units.Quantity`

            .. warning::
                Must be set **before**
                :attr:`~nenupy.observation.tapdatabase.ObsDatabase.fov_center`.
        """
        return self._fov_radius

    @fov_radius.setter
    def fov_radius(self, r):
        if r is None:
            r = 180 * u.deg
        if not isinstance(r, u.Quantity):
            r *= u.deg
        if not r.isscalar:
            raise ValueError('FOV radius must be a scalar.')
        self._fov_radius = r
        return

    @property
    def fov_center(self):
        """ Center of the field of view queried, in comination
            with the radius :attr:`~nenupy.observation.tapdatabase.ObsDatabase.fov_radius`.

            :setter: Center of the field of view.
            
            :getter: Center of the field of view.

            :type: :class:`~astropy.coordinates.SkyCoord`

            .. warning::
                Must be set **after**
                :attr:`~nenupy.observation.tapdatabase.ObsDatabase.fov_radius`.
        """
        return self._fov_center

    @fov_center.setter
    def fov_center(self, f):
        if f is None:
            self._conditions['pos'] = ''
            self._fov_center = f
            return
        if not isinstance(f, SkyCoord):
            raise TypeError('fov_center must be a SkyCoord instance.')
        if not f.isscalar:
            raise ValueError('fov_center must be scalar.')
        radius = self.fov_radius.to(u.deg).value
        self._conditions['pos'] = f'1 = CONTAINS'\
            f"(POINT('ICRS', s_ra, s_dec), CIRCLE('ICRS', "\
            f'{f.ra.deg}, {f.dec.deg}, {radius}))'
        log.info(f'fov_center set to {f}, radius={radius} deg.')
        self._fov_center = f
        return

    @property
    def conditions(self):
        """ Conditions summary of the query.

            :getter: Query conditions.

            :type: `str`
        """
        conds = []
        for key in self._conditions.keys():
            if self._conditions[key] != '':
                conds.append(self._conditions[key])
        conditions = ' AND '.join(conds)
        return conditions

    @property
    def query(self):
        """ Full query, combining returned parameteres
            :attr:`~nenupy.observation.tapdatabase.ObsDatabase.meta_names`
            and the conditions
            :attr:`~nenupy.observation.tapdatabase.ObsDatabase.conditions`.

            :getter: Query.

            :type: `str`
        """
        q = f'SELECT {self.meta_names} from nenufar.bst '\
            f'WHERE ({self.conditions})'
        return q

    # --------------------------------------------------------- #
    # ------------------------ Methods ------------------------ #
    def search(self):
        """ Run the TAP :attr:`~nenupy.observation.tapdatabase.ObsDatabase.query`
            on the `NenuFAR BST service <http://vogate.obs-nancay.fr/tap>`_.

            :returns:
                NenuFAR observation properties resulting from the
                ADQL query.
            :rtype: :class:`~astropy.table.Table`
        """
        if self.conditions == '':
            raise ValueError('Empty query, fill out some attributes first.')
        log.info(f'TAP service columns to return: {self._meta_names}.')
        log.debug(f"Querying: '{self.query}'")
        result = self.service.search(self.query)
        return result.to_table()

    def reset(self):
        """ Reset query parameters to default values.
        """
        self.meta_names = [
            'target_name', 'obs_creator_did', 's_ra', 's_dec', 't_min',
            't_max', 'em_min', 'em_max'
        ]
        self.time_range = [None, None]
        self.freq_range = [None, None]
        self.fov_radius = 180 * u.deg
        self.fov_center = None
        log.info('Query parameters reset to default values.')
        return