Пример #1
0
def doquery_from_table(table):
    #Execute a TAP+ query using information from a single row of an astropy table
    server = TapPlus(url = table['queryurl'], \
                     default_protocol_is_https = True, \
                     verbose = True)
    if table['upload_table_name'] == '':
        result = server.launch_job_async(query = table['query'], verbose = True, \
                                         dump_to_file = True, output_file = table['outfile'])
    else:
        result = server.launch_job_async(query = table['query'], verbose = True, \
                                         dump_to_file = True, output_file = table['outfile'], \
                                         upload_table_name = table['upload_table_name'], \
                                         upload_resource = table['upload_resource'])
    return result
Пример #2
0
def _download_ps_table():
    exoarch = TapPlus(url="https://exoplanetarchive.ipac.caltech.edu/TAP")
    job = exoarch.launch_job_async("select * from ps")
    # TODO: fix dtype conversion
    df = job.get_results().to_pandas()
    setattr(df, "_is_ps_table", True)
    return df
Пример #3
0
def getColumns(catalog):
    from astroquery.utils.tap.core import TapPlus
    tap = TapPlus(url="http://TAPVizieR.u-strasbg.fr/TAPVizieR/tap") 
    query_string = """SELECT Top 1 * FROM {}""".format(catalog)
    job = tap.launch_job_async(query_string, dump_to_file=False)
    res = job.get_results()
    return res.columns
Пример #4
0
def master_table_query(args):

    import numpy as np
    import pandas as pd
    import time
    import datetime
    from astroquery.utils.tap.core import TapPlus

    if args.verbose > 0:
        print
        print '* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *'
        print 'master_table_query'
        print '* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *'
        print

    print datetime.datetime.now()

    # Extract info from argument list...
    outputFile = args.outputFile
    object_id_lo = args.object_id_lo
    object_id_hi = args.object_id_hi

    # Establish TAP connection to SkyMapper database...
    skymapper = TapPlus(url="http://skymappertap.asvo.nci.org.au/ncitap/tap")

    # Formulate the query...
    query = """SELECT * FROM dr1.master where object_id between %d and %d""" \
        % (object_id_lo, object_id_hi)
    if args.verbose > 0:
        print "Query:  ", query

    # Submit the query as an asynchronous job...
    if args.verbose > 0:
        print "Query start:      ", datetime.datetime.now()
    job = skymapper.launch_job_async(query)
    if args.verbose > 0:
        print "Query completed:  ", datetime.datetime.now()

    # Retrieve the results as an astropy Table...
    if args.verbose > 0:
        print "Retrieval start:      ", datetime.datetime.now()
    master_table = job.get_results()
    if args.verbose > 0:
        print "Retrieval completed:  ", datetime.datetime.now()

    # Sort table by image_id
    master_table.sort('object_id')

    # Save table to outputFile...
    if args.verbose > 0:
        print "File output start:      ", datetime.datetime.now()
    master_table.write(outputFile)
    if args.verbose > 0:
        print "File output completed:  ", datetime.datetime.now()

    if args.verbose > 0: print

    return 0
Пример #5
0
    def test_abort_job(self):
        connHandler = DummyConnHandler()
        tap = TapPlus("http://test:1111/tap", connhandler=connHandler)
        jobid = '12345'
        # Phase POST response
        responsePhase = DummyResponse()
        responsePhase.set_status_code(200)
        responsePhase.set_message("OK")
        responsePhase.set_data(method='POST',
                               context=None,
                               body=None,
                               headers=None)
        req = "async/" + jobid + "/phase?PHASE=ABORT"
        connHandler.set_response(req, responsePhase)
        # Launch response
        responseLaunchJob = DummyResponse()
        responseLaunchJob.set_status_code(303)
        responseLaunchJob.set_message("OK")
        # list of list (httplib implementation for headers in response)
        launchResponseHeaders = [[
            'location', 'http://test:1111/tap/async/' + jobid
        ]]
        responseLaunchJob.set_data(method='POST',
                                   context=None,
                                   body=None,
                                   headers=launchResponseHeaders)
        query = 'query'
        dictTmp = {
            "REQUEST": "doQuery",
            "LANG": "ADQL",
            "FORMAT": "votable",
            "tapclient": str(TAP_CLIENT_ID),
            "QUERY": str(query)
        }
        sortedKey = taputils.taputil_create_sorted_dict_key(dictTmp)
        req = "async?" + sortedKey
        connHandler.set_response(req, responseLaunchJob)

        job = tap.launch_job_async(query, autorun=False)
        assert job is not None, "Expected a valid job"
        assert job.get_phase() == 'PENDING', \
            "Wrong job phase. Expected: %s, found %s" % \
            ('PENDING', job.get_phase())
        # abort job
        job.abort()
        assert job.get_phase() == 'ABORT', \
            "Wrong job phase. Expected: %s, found %s" % \
            ('ABORT', job.get_phase())
        # try to abort again
        with pytest.raises(Exception):
            job.abort()
Пример #6
0
    def download_extended_catalog(self, merge=True):
        """ Dowloads smaller catalog source from PS:
        https://outerspace.stsci.edu/display/PANSTARRS/PS1+Source+extraction+and+catalogs
        
        Here merging:
        StackModelFitDeV: 
            Contains the de Vaucouleurs fit parameters for stack
            detections brighter than some limit (is this a S/N cut or a mag limit?) 
            outside the galactic plane. 
            All filters are matched into a single row. 
            Given are mag, radius, axial ratio, position angle, RA, Dec, chisq of fit.
        
        StackModelFitSer: 
            Contains the Sersic fit parameters for stack 
            detections brighter than magnitude 21.5 outside the galactic plane. 
            All filters are matched into a single row. 
            Given are mag, radius, axial ratio, Sersic index, position angle, RA, Dec, chisq of fit.


        """
        if self.catdata is None:
            self.download_catalog(update=True)
        objid = ",".join(["%s" % s for s in self.catdata["objID"].values])

        from astroquery.utils.tap.core import TapPlus
        tap_service = TapPlus(
            url="http://vao.stsci.edu/PS1DR2/tapservice.aspx")

        job = tap_service.launch_job_async("""
        SELECT *
        FROM dbo.StackModelFitDeV AS dev
        LEFT JOIN dbo.StackModelFitSer AS ser
            ON dev.objID = ser.objID
        WHERE
        dev.objID IN ({})
        """.format(objid))
        results = job.get_results().to_pandas()

        if merge:
            self._catdata = pandas.merge(self.catdata, results, on="objID")
            self._is_extended_cat_set = True
        else:
            self._is_extended_cat_set = False
            return results
Пример #7
0
def query_gaia():
    gaia = TapPlus(url='http://gea.esac.esa.int/tap-server/tap')

    job = gaia.launch_job_async('select top 100000 ra, dec, phot_g_mean_mag \
        from gaiadr1.gaia_source order by source_id')

    results = job.get_results()

    results = np.array(
        [result.as_void().view((float, 3)) for result in results])

    x = results[:, 2] * np.cos(results[:, 0]) * np.cos(results[:, 1])
    y = results[:, 2] * np.sin(results[:, 0]) * np.cos(results[:, 1])
    z = results[:, 2] * np.sin(results[:, 1])

    sample_size = 1000
    random_idns = np.random.choice(results.shape[0], sample_size)

    ax.scatter(x[random_idns], y[random_idns], z[random_idns], s=3)

    plt.show()
Пример #8
0
class ESAHubbleClass(BaseQuery):
    """
    Class to init ESA Hubble Module and communicate with eHST TAP
    """

    data_url = conf.DATA_ACTION
    metadata_url = conf.METADATA_ACTION
    TIMEOUT = conf.TIMEOUT
    calibration_levels = {
        0: "AUXILIARY",
        1: "RAW",
        2: "CALIBRATED",
        3: "PRODUCT"
    }
    copying_string = "Copying file to {0}..."

    def __init__(self, tap_handler=None):
        super(ESAHubbleClass, self).__init__()

        if tap_handler is None:
            self._tap = TapPlus(url="http://hst.esac.esa.int"
                                "/tap-server/tap/")
        else:
            self._tap = tap_handler

    def download_product(self,
                         observation_id,
                         calibration_level="RAW",
                         filename=None,
                         verbose=False):
        """
        Download products from EHST

        Parameters
        ----------
        observation_id : string
            id of the observation to be downloaded, mandatory
            The identifier of the observation we want to retrieve, regardless
            of whether it is simple or composite.
        calibration_level : string
            calibration level, optional, default 'RAW'
            The identifier of the data reduction/processing applied to the
            data. By default, the most scientifically relevant level will be
            chosen. RAW, CALIBRATED, PRODUCT or AUXILIARY
        filename : string
            file name to be used to store the artifact, optional, default
            None
            File name for the observation.
        verbose : bool
            optional, default 'False'
            flag to display information about the process

        Returns
        -------
        None. It downloads the observation indicated
        """

        params = {
            "OBSERVATION_ID": observation_id,
            "CALIBRATION_LEVEL": calibration_level
        }

        if filename is None:
            filename = observation_id + ".tar"

        response = self._request('GET',
                                 self.data_url,
                                 save=True,
                                 cache=True,
                                 params=params)

        if verbose:
            log.info(self.data_url + "?OBSERVATION_ID=" + observation_id +
                     "&CALIBRATION_LEVEL=" + calibration_level)
            log.info(self.copying_string.format(filename))

        shutil.move(response, filename)

    def get_artifact(self, artifact_id, filename=None, verbose=False):
        """
        Download artifacts from EHST. Artifact is a single Hubble product file.

        Parameters
        ----------
        artifact_id : string
            id of the artifact to be downloaded, mandatory
            The identifier of the physical product (file) we want to retrieve.
        filename : string
            file name to be used to store the artifact, optional, default None
            File name for the artifact
        verbose : bool
            optional, default 'False'
            flag to display information about the process

        Returns
        -------
        None. It downloads the artifact indicated
        """

        params = {"ARTIFACT_ID": artifact_id}
        response = self._request('GET',
                                 self.data_url,
                                 save=True,
                                 cache=True,
                                 params=params)
        if filename is None:
            filename = artifact_id

        if verbose:
            log.info(self.data_url + "?ARTIFACT_ID=" + artifact_id)
            log.info(self.copying_string.format(filename))

        shutil.move(response, filename)

    def get_postcard(self,
                     observation_id,
                     calibration_level="RAW",
                     resolution=256,
                     filename=None,
                     verbose=False):
        """
        Download postcards from EHST

        Parameters
        ----------
        observation_id : string
            id of the observation for which download the postcard, mandatory
            The identifier of the observation we want to retrieve, regardless
            of whether it is simple or composite.
        calibration_level : string
            calibration level, optional, default 'RAW'
            The identifier of the data reduction/processing applied to the
            data. By default, the most scientifically relevant level will be
            chosen. RAW, CALIBRATED, PRODUCT or AUXILIARY
        resolution : integer
            postcard resolution, optional, default 256
            Resolution of the retrieved postcard. 256 or 1024
        filename : string
            file name to be used to store the postcard, optional, default None
            File name for the artifact
        verbose : bool
            optional, default 'False'
            Flag to display information about the process

        Returns
        -------
        None. It downloads the observation postcard indicated
        """

        params = {
            "RETRIEVAL_TYPE": "POSTCARD",
            "OBSERVATION_ID": observation_id,
            "CALIBRATION_LEVEL": calibration_level,
            "RESOLUTION": resolution
        }

        response = self._request('GET',
                                 self.data_url,
                                 save=True,
                                 cache=True,
                                 params=params)

        if filename is None:
            filename = observation_id

        if verbose:
            log.info(self.data_url + "&".join([
                "?RETRIEVAL_TYPE=POSTCARD", "OBSERVATION_ID=" +
                observation_id, "CALIBRATION_LEVEL=" +
                calibration_level, "RESOLUTION=" + str(resolution)
            ]))
            log.info(self.copying_string.format(filename))

        shutil.move(response, filename)

    def cone_search(self,
                    coordinates,
                    radius=0.0,
                    filename=None,
                    output_format='votable',
                    cache=True):
        """
        """
        coord = self._getCoordInput(coordinates, "coordinate")
        radiusInGrades = float(radius / 60)  # Converts to degrees

        raHours, dec = commons.coord_to_radec(coord)
        ra = raHours * 15.0  # Converts to degrees
        payload = {
            "RESOURCE_CLASS":
            "OBSERVATION",
            "ADQLQUERY":
            "SELECT DISTINCT OBSERVATION,OBSERVATION.TYPE,"
            "TARGET.MOVING_TARGET"
            ",TARGET.TARGET_NAME,TARGET.TARGET_DESCRIPTION,PROPOSAL."
            "PROPOSAL_ID,PROPOSAL.PI_"
            "NAME,PROPOSAL.PROPOSAL_TITLE,INSTRUMENT.INSTRUMENT_NAME,"
            "PLANE.METADATA_PROVENANCE"
            ",PLANE.DATA_PRODUCT_TYPE,PLANE.SOFTWARE_VERSION,POSITION"
            ".RA,POSITION.DEC,POSITION."
            "GAL_LAT,POSITION.GAL_LON,POSITION.ECL_LAT,POSITION.ECL_LON"
            ",POSITION.FOV_SIZE,ENERGY."
            "WAVE_CENTRAL,ENERGY.WAVE_BANDWIDTH,ENERGY.WAVE_MAX,ENERGY"
            ".WAVE_MIN,ENERGY.FILTER FROM"
            " FIELD_NOT_USED  WHERE OBSERVATION.COLLECTION='HST'  AND  "
            "PLANE.MAIN_SCIENCE_PLANE="
            "'true'  AND  (OBSERVATION.TYPE='HST Composite' OR "
            "OBSERVATION.TYPE='HST Singleton')"
            "  AND  INTERSECTS(CIRCLE('ICRS', {0}, {1}, {2}"
            "),POSITION)=1  AND  PLANE.MAIN_SCIENCE_PLANE='true' "
            "ORDER BY PROPOSAL.PROPOSAL_ID "
            "DESC".format(str(ra), str(dec), str(radiusInGrades)),
            "RETURN_TYPE":
            str(output_format)
        }
        response = self._request('GET',
                                 self.metadata_url,
                                 params=payload,
                                 cache=cache,
                                 timeout=self.TIMEOUT)

        if filename is None:
            filename = "cone." + str(output_format)

        if response is None:
            table = None
        else:
            fileobj = BytesIO(response.content)
            table = Table.read(fileobj, format=output_format)
            # TODO: add "correct units" material here

        return table

    def query_metadata(self, output_format='votable', verbose=False):
        return

    def query_target(self,
                     name,
                     filename=None,
                     output_format='votable',
                     verbose=False):
        """
        It executes a query over EHST and download the xml with the results.

        Parameters
        ----------
        name : string
            target name to be requested, mandatory
        filename : string
            file name to be used to store the metadata, optional, default None
        output_format : string
            optional, default 'votable'
            output format of the query
        verbose : bool
            optional, default 'False'
            Flag to display information about the process

        Returns
        -------
        Table with the result of the query. It downloads metadata as a file.
        """

        params = {
            "RESOURCE_CLASS": "OBSERVATION",
            "SELECTED_FIELDS": "OBSERVATION",
            "QUERY": "(TARGET.TARGET_NAME=='" + name + "')",
            "RETURN_TYPE": str(output_format)
        }
        response = self._request('GET',
                                 self.metadata_url,
                                 save=True,
                                 cache=True,
                                 params=params)

        if verbose:
            log.info(self.metadata_url + "?RESOURCE_CLASS=OBSERVATION&"
                     "SELECTED_FIELDS=OBSERVATION&QUERY=(TARGET.TARGET_NAME"
                     "=='" + name + "')&RETURN_TYPE=" + str(output_format))
            log.info(self.copying_string.format(filename))
        if filename is None:
            filename = "target.xml"

        shutil.move(response, filename)

        return modelutils.read_results_table_from_file(filename,
                                                       str(output_format))

    def query_hst_tap(self,
                      query,
                      async_job=False,
                      output_file=None,
                      output_format="votable",
                      verbose=False):
        """Launches a synchronous or asynchronous job to query the HST tap

        Parameters
        ----------
        query : str, mandatory
            query (adql) to be executed
        async_job : bool, optional, default 'False'
            executes the query (job) in asynchronous/synchronous mode (default
            synchronous)
        output_file : str, optional, default None
            file name where the results are saved if dumpToFile is True.
            If this parameter is not provided, the jobid is used instead
        output_format : str, optional, default 'votable'
            results format
        verbose : bool, optional, default 'False'
            flag to display information about the process

        Returns
        -------
        A table object
        """
        if async_job:
            job = self._tap.launch_job_async(query=query,
                                             output_file=output_file,
                                             output_format=output_format,
                                             verbose=False,
                                             dump_to_file=output_file
                                             is not None)
        else:
            job = self._tap.launch_job(query=query,
                                       output_file=output_file,
                                       output_format=output_format,
                                       verbose=False,
                                       dump_to_file=output_file is not None)
        table = job.get_results()
        return table

    def query_criteria(self,
                       calibration_level=None,
                       data_product_type=None,
                       intent=None,
                       obs_collection=None,
                       instrument_name=None,
                       filters=None,
                       async_job=True,
                       output_file=None,
                       output_format="votable",
                       verbose=False,
                       get_query=False):
        """
        Launches a synchronous or asynchronous job to query the HST tap
        using calibration level, data product type, intent, collection,
        instrument name, and filters as criteria to create and execute the
        associated query.

        Parameters
        ----------
        calibration_level : str or int, optional
            The identifier of the data reduction/processing applied to the
            data. RAW (1), CALIBRATED (2), PRODUCT (3) or AUXILIARY (0)
        data_product_type : str, optional
            High level description of the product.
            image, spectrum or timeseries.
        intent : str, optional
            The intent of the original observer in acquiring this observation.
            SCIENCE or CALIBRATION
        collection : list of str, optional
            List of collections that are available in eHST catalogue.
            HLA, HST
        instrument_name : list of str, optional
            Name(s) of the instrument(s) used to generate the dataset
        filters : list of str, optional
            Name(s) of the filter(s) used to generate the dataset
        async_job : bool, optional, default 'True'
            executes the query (job) in asynchronous/synchronous mode (default
            synchronous)
        output_file : str, optional, default None
            file name where the results are saved if dumpToFile is True.
            If this parameter is not provided, the jobid is used instead
        output_format : str, optional, default 'votable'
            results format
        verbose : bool, optional, default 'False'
            flag to display information about the process
        get_query : bool, optional, default 'False'
            flag to return the query associated to the criteria as the result
            of this function.

        Returns
        -------
        A table object
        """

        parameters = []
        if calibration_level is not None:
            parameters.append("p.calibration_level LIKE '%{}%'".format(
                self.__get_calibration_level(calibration_level)))
        if data_product_type is not None:
            if isinstance(data_product_type, str):
                parameters.append("p.data_product_type LIKE '%{}%'".format(
                    data_product_type))
            else:
                raise ValueError("data_product_type must be a string")
        if intent is not None:
            if isinstance(intent, str):
                parameters.append("o.intent LIKE '%{}%'".format(intent))
            else:
                raise ValueError("intent must be a string")
        if self.__check_list_strings(obs_collection):
            parameters.append("(o.collection LIKE '%{}%')".format(
                "%' OR o.collection LIKE '%".join(obs_collection)))
        if self.__check_list_strings(instrument_name):
            parameters.append("(o.instrument_name LIKE '%{}%')".format(
                "%' OR o.instrument_name LIKE '%".join(instrument_name)))
        if self.__check_list_strings(filters):
            parameters.append(
                "(o.instrument_configuration LIKE '%{}%')".format(
                    "%' OR o.instrument_configuration "
                    "LIKE '%".join(filters)))
        query = "select o.*, p.calibration_level, p.data_product_type "\
                "from ehst.observation AS o LEFT JOIN ehst.plane as p "\
                "on o.observation_uuid=p.observation_uuid"
        if parameters:
            query += " where({})".format(" AND ".join(parameters))
        table = self.query_hst_tap(query=query,
                                   async_job=async_job,
                                   output_file=output_file,
                                   output_format=output_format,
                                   verbose=verbose)
        if verbose:
            log.info(query)
        if get_query:
            return query
        return table

    def __get_calibration_level(self, calibration_level):
        condition = ""
        if (calibration_level is not None):
            if isinstance(calibration_level, str):
                condition = calibration_level
            elif isinstance(calibration_level, int):
                if calibration_level < 4:
                    condition = self.calibration_levels[calibration_level]
                else:
                    raise KeyError("Calibration level must be between 0 and 3")
            else:
                raise KeyError("Calibration level must be either "
                               "a string or an integer")
        return condition

    def __check_list_strings(self, list):
        if list is None:
            return False
        if list and all(isinstance(elem, str) for elem in list):
            return True
        else:
            raise ValueError("One of the lists is empty or there are "
                             "elements that are not strings")

    def get_tables(self, only_names=True, verbose=False):
        """Get the available table in EHST TAP service

        Parameters
        ----------
        only_names : bool, TAP+ only, optional, default 'False'
            True to load table names only
        verbose : bool, optional, default 'False'
            flag to display information about the process

        Returns
        -------
        A list of tables
        """

        tables = self._tap.load_tables(only_names=only_names,
                                       include_shared_tables=False,
                                       verbose=verbose)
        if only_names is True:
            table_names = []
            for t in tables:
                table_names.append(t.name)
            return table_names
        else:
            return tables

    def get_columns(self, table_name, only_names=True, verbose=False):
        """Get the available columns for a table in EHST TAP service

        Parameters
        ----------
        table_name : string, mandatory, default None
            table name of which, columns will be returned
        only_names : bool, TAP+ only, optional, default 'False'
            True to load table names only
        verbose : bool, optional, default 'False'
            flag to display information about the process

        Returns
        -------
        A list of columns
        """

        tables = self._tap.load_tables(only_names=False,
                                       include_shared_tables=False,
                                       verbose=verbose)
        columns = None
        for t in tables:
            if str(t.name) == str(table_name):
                columns = t.columns
                break

        if columns is None:
            raise ValueError("table name specified is not found in "
                             "EHST TAP service")

        if only_names is True:
            column_names = []
            for c in columns:
                column_names.append(c.name)
            return column_names
        else:
            return columns

    def _getCoordInput(self, value, msg):
        if not (isinstance(value, str)
                or isinstance(value, commons.CoordClasses)):
            raise ValueError(
                str(msg) + ""
                " must be either a string or astropy.coordinates")
        if isinstance(value, str):
            coords = commons.parse_coordinates(value)
            return coords
        else:
            return value
Пример #9
0
from astroquery.utils.tap.core import TapPlus

# Select CSC2 sources within 1 arcsec from qso_farfrom_xsources.
# I'm using the CSC2 catalogue hosted in Vizier because
# I cannot make it work using the CXC TAP service
csc = TapPlus(url="http://tapvizier.u-strasbg.fr/TAPVizieR/tap")

query = (
    "SELECT t.SRCID_sdss, t.RA, t.DEC, "
    "DISTANCE(POINT('ICRS', t.RA, t.DEC), POINT('ICRS', m.RAICRS, m.DEICRS)) as d, "
    'm."2CXO", m.RAICRS, m.DEICRS, m."b_Fluxb", m.Fluxb, m."B_Fluxb", m.ExpAC, m.ExpHRC '
    'FROM "IX/57/csc2master" as m, tap_upload.qso_farfrom_xsources as t '
    "WHERE 1=CONTAINS(POINT('ICRS', t.RA, t.DEC), CIRCLE('ICRS', m.RAICRS, m.DEICRS, 1/3600.))"
)

# upload_resource is an Astropy table with the coordinates (columns RA, DEC)
# of all positions you want to query
job = csc.launch_job_async(
    query=query,
    upload_resource=upload_resource,
    upload_table_name="qso_farfrom_xsources",
)
csc_data = job.get_results()

csc_data["SRCID_sdss"] = csc_data["SRCID_sdss"].astype(str)
csc_data["_2CXO"] = csc_data["_2CXO"].astype(str)
csc_data.rename_column("_2CXO", "2CXO")

filename = data_folder.joinpath("qso_sdss_farfrom_4xmm_csc2.fits")
csc_data.write(str(filename), format="fits", overwrite=True)
Пример #10
0
def nobs_fs_table_query(args):

    import numpy as np
    import pandas as pd
    import time
    import datetime
    from astroquery.utils.tap.core import TapPlus

    if args.verbose>0: 
        print 
        print '* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *'
        print 'nobs_fs_table_query'
        print '* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *'
        print 

    print datetime.datetime.now()

    # Extract info from argument list...
    outputFile=args.outputFile
    
    # Establish TAP connection to SkyMapper database...
    skymapper = TapPlus(url="http://skymappertap.asvo.nci.org.au/ncitap/tap")

    # Formulate the query...
    query = """SELECT image_id, count(*) as nobj FROM dr1.fs_photometry group by image_id"""
    if args.verbose>0: 
        print "Query:  ", query
    
    # Submit the query as an asynchronous job...
    if args.verbose>0: 
        print "Query start:      ", datetime.datetime.now()
    job = skymapper.launch_job_async(query)
    if args.verbose>0: 
        print "Query completed:  ", datetime.datetime.now()

    # Retrieve the results as an astropy Table...
    if args.verbose>0: 
        print "Retrieval start:      ", datetime.datetime.now()
    nobs_fs_table = job.get_results()
    if args.verbose>0: 
        print "Retrieval completed:  ", datetime.datetime.now()

    # Sort table by image_id
    nobs_fs_table.sort('image_id')

    # Convert the results into a pandas data frame...
    #  (Could also use Table.to_pandas, but, unless careful,
    #   the image_id gets converted from an int64 to a float.)
    d = {'nobj':np.array(nobs_fs_table['nobj']), 'image_id':np.array(nobs_fs_table['image_id'])}
    df = pd.DataFrame(d)

    # Save dataframe to outputFile...
    if args.verbose>0: 
        print "File output start:      ", datetime.datetime.now()
    df.to_csv(outputFile,index=False)
    if args.verbose>0: 
        print "File output completed:  ", datetime.datetime.now()

    if args.verbose>0: print

    return 0
Пример #11
0
class ESAHubbleClass(BaseQuery):
    """
    Class to init ESA Hubble Module and communicate with eHST TAP
    """

    data_url = conf.DATA_ACTION
    metadata_url = conf.METADATA_ACTION
    target_url = conf.TARGET_ACTION
    TIMEOUT = conf.TIMEOUT
    calibration_levels = {
        0: "AUXILIARY",
        1: "RAW",
        2: "CALIBRATED",
        3: "PRODUCT"
    }
    product_types = ["PRODUCT", "SCIENCE_PRODUCT", "POSTCARD"]
    copying_string = "Copying file to {0}..."

    def __init__(self, tap_handler=None):
        super().__init__()

        if tap_handler is None:
            self._tap = TapPlus(url="http://hst.esac.esa.int"
                                "/tap-server/tap/")
        else:
            self._tap = tap_handler

    def download_product(self,
                         observation_id,
                         *,
                         calibration_level=None,
                         filename=None,
                         verbose=False,
                         product_type=None):
        """
        Download products from EHST based on their observation ID and the
        calibration level or the product type.

        Parameters
        ----------
        observation_id : string
            id of the observation to be downloaded, mandatory
            The identifier of the observation we want to retrieve, regardless
            of whether it is simple or composite.
        calibration_level : string
            calibration level, optional
            The identifier of the data reduction/processing applied to the
            data. By default, the most scientifically relevant level will be
            chosen. RAW, CALIBRATED, PRODUCT or AUXILIARY
        filename : string
            file name to be used to store the artifact, optional, default
            None
            File name for the observation.
        verbose : bool
            optional, default 'False'
            flag to display information about the process
        product_type : string
            type of product retrieval, optional
            PRODUCT, SCIENCE_PRODUCT or POSTCARD

        Returns
        -------
        None. It downloads the observation indicated
        """

        params = {
            "OBSERVATION_ID": observation_id,
            "USERNAME": "******"
        }
        url = self.data_url + "?OBSERVATION_ID=" + observation_id
        url += "&USERNAME="******"ehst-astroquery"

        if filename is None:
            filename = observation_id + ".tar"

        if calibration_level:
            params["CALIBRATION_LEVEL"] = calibration_level
            url += "&CALIBRATION_LEVEL=" + calibration_level

        if product_type:
            self.__validate_product_type(product_type)
            params["RETRIEVAL_TYPE"] = product_type
            filename = self._get_product_filename(product_type, filename)
            url += "&RETRIEVAL_TYPE=" + params["RETRIEVAL_TYPE"]

        response = self._request('GET',
                                 self.data_url,
                                 save=True,
                                 cache=True,
                                 params=params)

        if verbose:
            log.info(url)
            log.info(self.copying_string.format(filename))

        shutil.move(response, filename)

    def get_member_observations(self, observation_id):
        """
        Returns the related members of simple and composite observations

        Parameters
        ----------
        observation_id : str
            Observation identifier.

        Returns
        -------
        A list of strings with the observation_id of the associated
        observations
        """
        observation_type = self.get_observation_type(observation_id)

        if 'Composite' in observation_type:
            oids = self._select_related_members(observation_id)
        elif 'Simple' in observation_type:
            oids = self._select_related_composite(observation_id)
        else:
            raise ValueError("Invalid observation id")
        return oids

    def get_hap_hst_link(self, observation_id):
        """
        Returns the related members of hap and hst observations

        Parameters
        ----------
        observation_id : string
           id of the observation to be downloaded, mandatory
           The identifier of the observation we want to retrieve, regardless
           of whether it is simple or composite.

        Returns
        -------
        A list of strings with the observation_id of the associated
        observations
        """
        observation_type = self.get_observation_type(observation_id)
        if 'Composite' in observation_type:
            raise ValueError(
                "HAP-HST link is only available for simple observations. Input observation is Composite."
            )
        elif 'HAP' in observation_type:
            oids = self._select_related_members(observation_id)
        elif 'HST' in observation_type:
            query = f"select observation_id from ehst.observation where obs_type='HAP Simple' and members like '%{observation_id}%'"
            job = self.query_hst_tap(query=query)
            oids = job["observation_id"].pformat(show_name=False)
        else:
            raise ValueError("Invalid observation id")
        return oids

    def get_observation_type(self, observation_id):
        """
        Returns the type of an observation

        Parameters
        ----------
        observation_id : string
           id of the observation to be downloaded, mandatory
           The identifier of the observation we want to retrieve, regardless
           of whether it is simple or composite.

        Returns
        -------
        String with the observation type
        """
        if observation_id is None:
            raise ValueError("Please input an observation id")

        query = f"select obs_type from ehst.observation where observation_id='{observation_id}'"
        job = self.query_hst_tap(query=query)
        if any(job["obs_type"]):
            obs_type = self._get_decoded_string(string=job["obs_type"][0])
        else:
            raise ValueError("Invalid Observation ID")
        return obs_type

    def _select_related_members(self, observation_id):
        query = f"select members from ehst.observation where observation_id='{observation_id}'"
        job = self.query_hst_tap(query=query)
        oids = self._get_decoded_string(string=job["members"][0]).replace(
            "caom:HST/", "").split(" ")
        return oids

    def _select_related_composite(self, observation_id):
        query = f"select observation_id from ehst.observation where members like '%{observation_id}%'"
        job = self.query_hst_tap(query=query)
        oids = job["observation_id"].pformat(show_name=False)
        return oids

    def __validate_product_type(self, product_type):
        if (product_type not in self.product_types):
            raise ValueError("This product_type is not allowed")

    def _get_product_filename(self, product_type, filename):
        if (product_type == "PRODUCT"):
            return filename
        elif (product_type == "SCIENCE_PRODUCT"):
            log.info("This is a SCIENCE_PRODUCT, the filename will be "
                     "renamed to " + filename + ".fits.gz")
            return filename + ".fits.gz"
        else:
            log.info("This is a POSTCARD, the filename will be "
                     "renamed to " + filename + ".jpg")
            return filename + ".jpg"

    def get_artifact(self, artifact_id, filename=None, verbose=False):
        """
        Download artifacts from EHST. Artifact is a single Hubble product file.

        Parameters
        ----------
        artifact_id : string
            id of the artifact to be downloaded, mandatory
            The identifier of the physical product (file) we want to retrieve.
        filename : string
            file name to be used to store the artifact, optional, default None
            File name for the artifact
        verbose : bool
            optional, default 'False'
            flag to display information about the process

        Returns
        -------
        None. It downloads the artifact indicated
        """

        params = {"ARTIFACT_ID": artifact_id, "USERNAME": "******"}
        response = self._request('GET',
                                 self.data_url,
                                 save=True,
                                 cache=True,
                                 params=params)
        if filename is None:
            filename = artifact_id

        if verbose:
            log.info(self.data_url + "?ARTIFACT_ID=" + artifact_id +
                     "&USERNAME=ehst-astroquery")
            log.info(self.copying_string.format(filename))

        shutil.move(response, filename)

    def get_postcard(self,
                     observation_id,
                     calibration_level="RAW",
                     resolution=256,
                     filename=None,
                     verbose=False):
        """
        Download postcards from EHST

        Parameters
        ----------
        observation_id : string
            id of the observation for which download the postcard, mandatory
            The identifier of the observation we want to retrieve, regardless
            of whether it is simple or composite.
        calibration_level : string
            calibration level, optional, default 'RAW'
            The identifier of the data reduction/processing applied to the
            data. By default, the most scientifically relevant level will be
            chosen. RAW, CALIBRATED, PRODUCT or AUXILIARY
        resolution : integer
            postcard resolution, optional, default 256
            Resolution of the retrieved postcard. 256 or 1024
        filename : string
            file name to be used to store the postcard, optional, default None
            File name for the artifact
        verbose : bool
            optional, default 'False'
            Flag to display information about the process

        Returns
        -------
        None. It downloads the observation postcard indicated
        """

        params = {
            "RETRIEVAL_TYPE": "POSTCARD",
            "OBSERVATION_ID": observation_id,
            "CALIBRATION_LEVEL": calibration_level,
            "RESOLUTION": resolution,
            "USERNAME": "******"
        }

        response = self._request('GET',
                                 self.data_url,
                                 save=True,
                                 cache=True,
                                 params=params)

        if filename is None:
            filename = observation_id

        if verbose:
            log.info(self.data_url + "&".join([
                "?RETRIEVAL_TYPE=POSTCARD", "OBSERVATION_ID=" +
                observation_id, "CALIBRATION_LEVEL=" +
                calibration_level, "RESOLUTION=" +
                str(resolution), "USERNAME=ehst-astroquery"
            ]))
            log.info(self.copying_string.format(filename))

        shutil.move(response, filename)

    def cone_search(self,
                    coordinates,
                    radius,
                    filename=None,
                    output_format='votable',
                    cache=True,
                    async_job=False,
                    verbose=False):
        """
        To execute a cone search defined by a coordinate and a radius

        Parameters
        ----------
        coordinates : astropy.coordinate, mandatory
            coordinates of the center in the cone search
        radius : float or quantity
            radius in arcmin (int, float) or quantity of the cone_search
        filename : str, default None
            Path and name of the file to store the results.
            If the filename is defined, the file will be
            automatically saved
        output_format : string
            results format. Options are:
            'votable': str, binary VOTable format
            'csv': str, comma-separated values format
        async_job : bool, optional, default 'False'
            executes the query (job) in asynchronous/synchronous mode (default
            synchronous)
        cache : bool
            optional, default 'True'
            Flag to save the results in the local cache
        verbose : bool, optional, default 'False'
            flag to display information about the process

        Returns
        -------
        astropy.table.Table with the result of the cone_search
        """
        coord = self._getCoordInput(coordinates)
        if type(radius) == int or type(radius) == float:
            radius_in_grades = Angle(radius, units.arcmin).deg
        else:
            radius_in_grades = radius.to(units.deg).value
        ra = coord.ra.deg
        dec = coord.dec.deg
        query = (
            "select o.observation_id, "
            "o.start_time, o.end_time, o.start_time_mjd, "
            "o.end_time_mjd, o.exposure_duration, o.release_date, "
            "o.run_id, o.program_id, o.set_id, o.collection, "
            "o.members_number, o.instrument_configuration, "
            "o.instrument_name, o.obs_type, o.target_moving, "
            "o.target_name, o.target_description, o.proposal_id, "
            "o.pi_name, prop.title, pl.metadata_provenance, "
            "pl.data_product_type, pl.software_version, pos.ra, "
            "pos.dec, pos.gal_lat, pos.gal_lon, pos.ecl_lat, "
            "pos.ecl_lon, pos.fov_size, en.wave_central, "
            "en.wave_bandwidth, en.wave_max, en.wave_min, "
            "en.filter from ehst.observation o join ehst.proposal "
            "prop on o.proposal_id=prop.proposal_id join ehst.plane "
            "pl on pl.observation_id=o.observation_id join "
            "ehst.position pos on pos.plane_id = pl.plane_id join "
            "ehst.energy en on en.plane_id=pl.plane_id where "
            "pl.main_science_plane='true' and 1=CONTAINS(POINT('ICRS', "
            f"pos.ra, pos.dec),CIRCLE('ICRS', {str(ra)}, {str(dec)}, {str(radius_in_grades)})) order "
            "by prop.proposal_id desc")
        print("type: " + str(type(query)))
        if verbose:
            log.info(query)
        table = self.query_hst_tap(query=query,
                                   async_job=async_job,
                                   output_file=filename,
                                   output_format=output_format,
                                   verbose=verbose)
        return table

    def cone_search_criteria(self,
                             radius,
                             target=None,
                             coordinates=None,
                             calibration_level=None,
                             data_product_type=None,
                             intent=None,
                             obs_collection=None,
                             instrument_name=None,
                             filters=None,
                             async_job=True,
                             filename=None,
                             output_format='votable',
                             save=False,
                             cache=True,
                             verbose=False):
        """
        To execute a cone search defined by a coordinate (an
        astropy.coordinate element or a target name which is resolved),
        a radius and a set of criteria to filter the results. This function
        comprises the outputs of query_target, cone_search and query_criteria
        methods.

        Parameters
        ----------
        radius : float or quantity
            radius in arcmin (int, float) or quantity of the cone_search
        target : str, mandatory if no coordinates is provided
            name of the target, that will act as center in the cone search
        coordinates : astropy.coordinate, mandatory if no target is provided
            coordinates of the center in the cone search
        calibration_level : str or int, optional
            The identifier of the data reduction/processing applied to the
            data. RAW (1), CALIBRATED (2), PRODUCT (3) or AUXILIARY (0)
        data_product_type : str, optional
            High level description of the product.
            image, spectrum or timeseries.
        intent : str, optional
            The intent of the original observer in acquiring this observation.
            SCIENCE or CALIBRATION
        collection : list of str, optional
            List of collections that are available in eHST catalogue.
            HLA, HST
        instrument_name : list of str, optional
            Name(s) of the instrument(s) used to generate the dataset
        filters : list of str, optional
            Name(s) of the filter(s) used to generate the dataset
        async_job : bool, optional, default 'False'
            executes the query (job) in asynchronous/synchronous mode (default
            synchronous)
        filename : str, default None
            Path and name of the file to store the results.
            If the filename is defined, the file will be
            automatically saved
        output_format : string
            results format. Options are:
            'votable': str, binary VOTable format
            'csv': str, comma-separated values format
        save : bool
            optional, default 'False'
            Flag to save the result in a file. If the filename
            is not defined, it will use a formatted name to save
            the file
        cache : bool
            optional, default 'True'
            Flag to save the results in the local cache
        verbose : bool, optional, default 'False'
            flag to display information about the process

        Returns
        -------
        astropy.table.Table with the result of the cone_search
        """
        crit_query = self.query_criteria(calibration_level=calibration_level,
                                         data_product_type=data_product_type,
                                         intent=intent,
                                         obs_collection=obs_collection,
                                         instrument_name=instrument_name,
                                         filters=filters,
                                         async_job=True,
                                         get_query=True)
        if crit_query.endswith(")"):
            crit_query = crit_query[:-1] + " AND "
        else:
            crit_query = crit_query + " WHERE ("

        if target and coordinates:
            raise TypeError("Please use only target or coordinates as"
                            "parameter.")
        if target:
            coord = self._query_tap_target(target)
        else:
            coord = self._getCoordInput(coordinates)

        ra = coord.ra.deg
        dec = coord.dec.deg

        if type(radius) == int or type(radius) == float:
            radius_in_grades = Angle(radius, units.arcmin).deg
        else:
            radius_in_grades = radius.to(units.deg).value
        cone_query = "1=CONTAINS(POINT('ICRS', pos.ra, pos.dec)," \
                     "CIRCLE('ICRS', {0}, {1}, {2}))". \
            format(str(ra), str(dec), str(radius_in_grades))
        query = "{}{})".format(crit_query, cone_query)
        if verbose:
            log.info(query)

        table = self.query_hst_tap(query=query,
                                   async_job=async_job,
                                   output_file=filename,
                                   output_format=output_format,
                                   verbose=verbose)
        return table

    def _query_tap_target(self, target):
        try:
            params = {
                "TARGET_NAME": target,
                "RESOLVER_TYPE": "SN",
                "FORMAT": "json"
            }
            target_response = self._request('GET',
                                            self.target_url,
                                            cache=True,
                                            params=params)
            target_result = target_response.json()['data'][0]
            ra = target_result['RA_DEGREES']
            dec = target_result['DEC_DEGREES']
            return SkyCoord(ra=ra, dec=dec, unit="deg")
        except KeyError as e:
            raise ValueError("This target cannot be resolved")

    def query_metadata(self, output_format='votable', verbose=False):
        return

    def query_target(self,
                     name,
                     *,
                     filename=None,
                     output_format='votable',
                     verbose=False,
                     async_job=False,
                     radius=7):
        """
        It executes a query over EHST and download the xml with the results.

        Parameters
        ----------
        name : string
            target name to be requested, mandatory
        filename : string
            file name to be used to store the metadata, optional, default None
        output_format : string
            optional, default 'votable'
            output format of the query
        verbose : bool
            optional, default 'False'
            Flag to display information about the process
        async_job : bool, optional, default 'False'
            executes the query (job) in asynchronous/synchronous mode (default
            synchronous)
        radius : int
            optional, default 7
            radius in arcmin (int, float) or quantity of the cone_search

        Returns
        -------
        Table with the result of the query. It downloads metadata as a file.
        """
        coordinates = self._query_tap_target(name)
        table = self.cone_search(coordinates,
                                 radius,
                                 filename=filename,
                                 output_format=output_format,
                                 verbose=verbose,
                                 async_job=async_job)

        return table

    def query_hst_tap(self,
                      query,
                      async_job=False,
                      output_file=None,
                      output_format="votable",
                      verbose=False):
        """Launches a synchronous or asynchronous job to query the HST tap

        Parameters
        ----------
        query : str, mandatory
            query (adql) to be executed
        async_job : bool, optional, default 'False'
            executes the query (job) in asynchronous/synchronous mode (default
            synchronous)
        output_file : str, optional, default None
            file name where the results are saved if dumpToFile is True.
            If this parameter is not provided, the jobid is used instead
        output_format : str, optional, default 'votable'
            results format
        verbose : bool, optional, default 'False'
            flag to display information about the process

        Returns
        -------
        A table object
        """
        if async_job:
            job = self._tap.launch_job_async(query=query,
                                             output_file=output_file,
                                             output_format=output_format,
                                             verbose=verbose,
                                             dump_to_file=output_file
                                             is not None)
        else:
            job = self._tap.launch_job(query=query,
                                       output_file=output_file,
                                       output_format=output_format,
                                       verbose=verbose,
                                       dump_to_file=output_file is not None)
        table = job.get_results()
        return table

    def query_criteria(self,
                       calibration_level=None,
                       data_product_type=None,
                       intent=None,
                       obs_collection=None,
                       instrument_name=None,
                       filters=None,
                       async_job=True,
                       output_file=None,
                       output_format="votable",
                       verbose=False,
                       get_query=False):
        """
        Launches a synchronous or asynchronous job to query the HST tap
        using calibration level, data product type, intent, collection,
        instrument name, and filters as criteria to create and execute the
        associated query.

        Parameters
        ----------
        calibration_level : str or int, optional
            The identifier of the data reduction/processing applied to the
            data. RAW (1), CALIBRATED (2), PRODUCT (3) or AUXILIARY (0)
        data_product_type : str, optional
            High level description of the product.
            image, spectrum or timeseries.
        intent : str, optional
            The intent of the original observer in acquiring this observation.
            SCIENCE or CALIBRATION
        collection : list of str, optional
            List of collections that are available in eHST catalogue.
            HLA, HST
        instrument_name : list of str, optional
            Name(s) of the instrument(s) used to generate the dataset
        filters : list of str, optional
            Name(s) of the filter(s) used to generate the dataset
        async_job : bool, optional, default 'True'
            executes the query (job) in asynchronous/synchronous mode (default
            synchronous)
        output_file : str, optional, default None
            file name where the results are saved if dumpToFile is True.
            If this parameter is not provided, the jobid is used instead
        output_format : str, optional, default 'votable'
            results format
        verbose : bool, optional, default 'False'
            flag to display information about the process
        get_query : bool, optional, default 'False'
            flag to return the query associated to the criteria as the result
            of this function.

        Returns
        -------
        A table object
        """

        parameters = []
        if calibration_level is not None:
            parameters.append("p.calibration_level LIKE '%{}%'".format(
                self.__get_calibration_level(calibration_level)))
        if data_product_type is not None:
            if isinstance(data_product_type, str):
                parameters.append("p.data_product_type LIKE '%{}%'".format(
                    data_product_type))
            else:
                raise ValueError("data_product_type must be a string")
        if intent is not None:
            if isinstance(intent, str):
                parameters.append("o.intent LIKE '%{}%'".format(intent))
            else:
                raise ValueError("intent must be a string")
        if self.__check_list_strings(obs_collection):
            parameters.append("(o.collection LIKE '%{}%')".format(
                "%' OR o.collection LIKE '%".join(obs_collection)))
        if self.__check_list_strings(instrument_name):
            parameters.append("(o.instrument_name LIKE '%{}%')".format(
                "%' OR o.instrument_name LIKE '%".join(instrument_name)))
        if self.__check_list_strings(filters):
            parameters.append(
                "(o.instrument_configuration LIKE '%{}%')".format(
                    "%' OR o.instrument_configuration "
                    "LIKE '%".join(filters)))
        query = "select o.*, p.calibration_level, p.data_product_type, " \
                "pos.ra, pos.dec from ehst.observation AS o JOIN " \
                "ehst.plane as p on o.observation_uuid=p.observation_uuid " \
                "JOIN ehst.position as pos on p.plane_id = pos.plane_id"
        if parameters:
            query += " where({})".format(" AND ".join(parameters))
        if verbose:
            log.info(query)
        if get_query:
            return query
        table = self.query_hst_tap(query=query,
                                   async_job=async_job,
                                   output_file=output_file,
                                   output_format=output_format,
                                   verbose=verbose)
        return table

    def __get_calibration_level(self, calibration_level):
        condition = ""
        if (calibration_level is not None):
            if isinstance(calibration_level, str):
                condition = calibration_level
            elif isinstance(calibration_level, int):
                if calibration_level < 4:
                    condition = self.calibration_levels[calibration_level]
                else:
                    raise KeyError("Calibration level must be between 0 and 3")
            else:
                raise KeyError("Calibration level must be either "
                               "a string or an integer")
        return condition

    def __check_list_strings(self, list):
        if list is None:
            return False
        if list and all(isinstance(elem, str) for elem in list):
            return True
        else:
            raise ValueError("One of the lists is empty or there are "
                             "elements that are not strings")

    def get_tables(self, only_names=True, verbose=False):
        """Get the available table in EHST TAP service

        Parameters
        ----------
        only_names : bool, TAP+ only, optional, default 'False'
            True to load table names only
        verbose : bool, optional, default 'False'
            flag to display information about the process

        Returns
        -------
        A list of tables
        """

        tables = self._tap.load_tables(only_names=only_names,
                                       include_shared_tables=False,
                                       verbose=verbose)
        if only_names is True:
            table_names = []
            for t in tables:
                table_names.append(t.name)
            return table_names
        else:
            return tables

    def get_columns(self, table_name, only_names=True, verbose=False):
        """Get the available columns for a table in EHST TAP service

        Parameters
        ----------
        table_name : string, mandatory, default None
            table name of which, columns will be returned
        only_names : bool, TAP+ only, optional, default 'False'
            True to load table names only
        verbose : bool, optional, default 'False'
            flag to display information about the process

        Returns
        -------
        A list of columns
        """

        tables = self._tap.load_tables(only_names=False,
                                       include_shared_tables=False,
                                       verbose=verbose)
        columns = None
        for t in tables:
            if str(t.name) == str(table_name):
                columns = t.columns
                break

        if columns is None:
            raise ValueError("table name specified is not found in "
                             "EHST TAP service")

        if only_names is True:
            column_names = []
            for c in columns:
                column_names.append(c.name)
            return column_names
        else:
            return columns

    def _getCoordInput(self, value):
        if not (isinstance(value, str) or isinstance(value, SkyCoord)):
            raise ValueError("Coordinates" +
                             " must be either a string or astropy.coordinates")
        if isinstance(value, str):
            return SkyCoord(value)
        else:
            return value

    def _get_decoded_string(self, string):
        try:
            return string.decode('utf-8')
        except (UnicodeDecodeError, AttributeError):
            return string
Пример #12
0
def find_outliers(vis, refant, dopol, nloops, loop, cell, robust, imsize,
                  wprojplanes, niter, threshold, uvrange, nterms, gridder,
                  deconvolver, solint, calmode, discard_nloops, gaintype,
                  outlier_threshold, flag, step):

    local = locals()
    local.pop('step')
    imbase, imagename, outimage, pixmask, rmsfile, caltable, prev_caltables, threshold, outlierfile, cfcache, thresh, maskfile = bookkeeping.get_selfcal_args(
        vis,
        loop,
        nloops,
        nterms,
        deconvolver,
        discard_nloops,
        calmode,
        outlier_threshold,
        threshold,
        step=step)
    cat = imagename + ".catalog.fits"
    outlierfile_all = 'outliers.txt'
    fitsname = imagename + '.fits'
    outlier_imsize = 128
    outlier_snr = 5
    sky_model_radius = 2  #degrees

    if step != 'sky':
        pybdsf(imbase, rmsfile, imagename, outimage, thresh, maskfile, cat)

    #Store before potentially updating to mJy
    orig_threshold = outlier_threshold

    if outlier_threshold != '' and outlier_threshold != 0:

        #Take sky positions from RACS
        if step == 'sky':
            from astroquery.utils.tap.core import TapPlus
            from astropy.table import vstack

            #Open MS and extract first target centre; use first sub-MS for speed if MMS
            if os.path.exists('{0}/SUBMSS'.format(vis)):
                tmpvis = glob.glob('{0}/SUBMSS/*'.format(vis))[0]
            else:
                tmpvis = vis
            msmd.open(tmpvis)
            dir = msmd.sourcedirs()[str(msmd.fieldsforintent('TARGET')[0])]
            ra = qa.convert(dir['m0'], 'deg')['value']
            dec = qa.convert(dir['m1'], 'deg')['value']
            if ra < 0:
                ra += 360
            phasecenter = SkyCoord(ra=ra, dec=dec, unit='deg,deg')
            msmd.done()

            cat = 'RACS_local.fits'
            fluxcol = 'total_flux_source'
            efluxcol = 'e_total_flux_source'
            racol = 'ra'
            deccol = 'dec'
            outlier_threshold *= 1e3  #convert from mJy to Jy

            #Extract RACS positions within sky_model_radius
            try:
                casdatap = TapPlus(
                    url="https://casda.csiro.au/casda_vo_tools/tap")
                query = "SELECT * FROM  AS110.racs_dr1_sources_galacticcut_v2021_08_v01 where 1=CONTAINS(POINT('ICRS', ra, dec),CIRCLE('ICRS',{0},{1},{2}))".format(
                    ra, dec, sky_model_radius)
                job = casdatap.launch_job_async(query)
                galcut = job.get_results()
                job = casdatap.launch_job_async(query.replace('cut', 'region'))
                galregion = job.get_results()
                RACS = vstack([galcut, galregion], join_type='exact')
                RACS.write(cat, overwrite=True)
            except:
                RACS = '{0}/RACS.fits.gz'.format(processMeerKAT.SCRIPT_DIR)
                tmp = fits.open(RACS)
                all_positions = SkyCoord(ra=tmp[1].data[racol],
                                         dec=tmp[1].data[deccol],
                                         unit='deg,deg')
                tmp[1].data = tmp[1].data[phasecenter.separation(all_positions)
                                          < Quantity(sky_model_radius, 'deg')]
                tmp.writeto(cat, overwrite=True)
                tmp.close()
                del all_positions  #Don't store millions of positions beyond here

            index = loop

        else:
            fluxcol = 'Total_flux'
            efluxcol = 'E_Total_flux'
            racol = 'RA'
            deccol = 'Dec'
            index = loop + 1

        # Write initial outlier file
        if step == 'sky':
            tab = fits.open(cat)
            data = tab[1].data
            tab.close()

            if orig_threshold > 1.0:
                metric = data[fluxcol] / data[efluxcol]
            else:
                metric = data[fluxcol]

            outliers = data[metric > outlier_threshold]
            out = open(outlierfile_all, 'w')
            mask = 'mask={0}'.format(pixmask)  # if pixmask != '' else ''

            for i, row in enumerate(outliers):
                SkyPos = SkyCoord(ra=row[racol],
                                  dec=row[deccol],
                                  unit='deg,deg')
                position = 'J2000 {0}'.format(SkyPos.to_string('hmsdms'))
                out.write("""
                imagename={0}_outlier{1}
                imsize=[{2},{2}]
                cell=[1.0arcsec,1.0arcsec]
                phasecenter={3}
                nterms={4}
                gridder=standard
                {5}\n""".format(imbase % (index), i, outlier_imsize, position,
                                nterms[loop], mask))

            out.close()

            if os.path.exists(outlierfile_all):
                logger.info(
                    "All 'outliers' within field written to '{0}' based on catalog '{1}'."
                    .format(outlierfile_all,
                            os.path.split(cat)[1]))
            else:
                logger.error(
                    "Outlier file '{0}' doesn't exist, so sky model build went wrong. Will terminate process."
                    .format(outlierfile_all))
                sys.exit(1)

        #Write outlier file specific to this loop
        if not os.path.exists(outlierfile_all) and os.path.exists(
                '../{0}'.format(outlierfile_all)):
            logger.warning(
                'Using outliers from ../{0}'.format(outlierfile_all))
            outlierfile_all = '../{0}'.format(outlierfile_all)
        outliers = open(outlierfile_all).read()
        out = open(outlierfile, 'w')

        if os.path.exists(fitsname):
            img = fits.open(fitsname)
            head = img[0].header
            img.close()
            index = loop + 1
        elif step == 'sky':
            img = fits.PrimaryHDU()
            head = img.header
            head['CUNIT1'] = 'deg'
            head['CUNIT2'] = 'deg'
            head['CTYPE1'] = 'RA---SIN'
            head['CTYPE2'] = 'DEC--SIN'
            head['CRVAL1'] = ra
            head['CRVAL2'] = dec
            index = loop

        #Update header to reflect image, and pop degenerate axes
        imsize = imsize[index]
        cell = cell[index]
        if type(imsize) is not list:
            imsize = [imsize, imsize]
        if type(cell) is not list:
            cell = [cell, cell]

        head['NAXIS1'] = imsize[0]
        head['NAXIS2'] = imsize[1]
        head['CRPIX1'] = int(imsize[0] / 2 + 1)
        head['CRPIX2'] = int(imsize[1] / 2 + 1)

        xdelt = qa.convert(cell[0], 'deg')['value']
        ydelt = qa.convert(cell[1], 'deg')['value']
        if 'CDELT1' in head.keys() and head['CDELT1'] > 0:
            head['CDELT1'] = xdelt
        else:
            head['CDELT1'] = -xdelt
        if 'CDELT2' in head.keys() and head['CDELT2'] < 0:
            head['CDELT2'] = -ydelt
        else:
            head['CDELT2'] = ydelt

        head['NAXIS'] = 2
        for axis in ['NAXIS3', 'NAXIS4']:
            if axis in head.keys():
                head.pop(head.index(axis))

        w = WCS(head)
        r = re.compile(r'phasecenter=J2000 (?P<ra>.*?) (?P<dec>.*?)\n')
        positions = [m.groupdict() for m in r.finditer(outliers)]
        outlier_bases = re.findall(r'imagename=(.*)\n', outliers)
        num_outliers = 0

        #Only write positions for this loop outside imaging area
        for i, position in enumerate(positions):
            pos = SkyCoord(**position)
            if not w.footprint_contains(pos):
                num_outliers += 1
                mask = 'mask={0}'.format(pixmask)
                phasecenter = 'J2000 {0}'.format(pos.to_string('hmsdms'))

                if step == 'bdsf':
                    base = outlier_bases[i]
                    im = base + '.image'
                    outlier_cat = base + ".catalog.fits"
                    outlier_mask = '{0}.islmask'.format(base)

                    if nterms[loop] > 1 and deconvolver[loop] == 'mtmfs':
                        im += '.tt0'

                    if os.path.exists(im):
                        #Run PyBDSF on outlier and update mask
                        pybdsf(imbase,
                               rmsfile,
                               base,
                               im,
                               outlier_snr,
                               outlier_mask,
                               outlier_cat,
                               write_all=False)
                        outlier_pixmask = mask_image(**local,
                                                     outlier_base=base,
                                                     outlier_image=im)
                    else:
                        #Use main image, run PyBDSF on box around outlier, and update mask
                        ia.open(outimage)
                        pix = ia.topixel(pos.to_string('hmsdms'))['numeric']
                        x, y = pix[0], pix[1]
                        delta = outlier_imsize / 2
                        trim_box = (x - delta, x + delta, y - delta, y + delta)
                        ia.close()

                        pybdsf(imbase,
                               rmsfile,
                               imagename,
                               outimage,
                               outlier_snr,
                               outlier_mask,
                               outlier_cat,
                               trim_box=trim_box,
                               write_all=False)
                        outlier_pixmask = mask_image(**local,
                                                     outlier_base=base)

                    mask = 'mask={0}'.format(outlier_pixmask)

                    #If catalog written, take new PyBDSF position closest to previous position
                    if os.path.exists(outlier_cat):
                        tab = fits.open(outlier_cat)
                        data = tab[1].data
                        tab.close()
                        cat_positions = SkyCoord(ra=data['RA'],
                                                 dec=data['Dec'],
                                                 unit='deg,deg')
                        row, _, _ = pos.match_to_catalog_sky(cat_positions)
                        phasecenter = 'J2000 {0}'.format(
                            cat_positions[row].to_string('hmsdms'))
                    else:
                        logger.warning(
                            "PyBDSF catalogue '{0}' not created. Using old position and mask."
                            .format(outlier_cat))
                        mask = 'mask={0}'.format(pixmask)

                out.write("""
                imagename={0}_outlier{1}
                imsize=[{2},{2}]
                cell=[1.0arcsec,1.0arcsec]
                phasecenter={3}
                nterms={4}
                gridder=standard
                {5}\n""".format(imbase % (index), i, outlier_imsize,
                                phasecenter, nterms[loop], mask))

            else:
                logger.info(
                    'Excluding "{0}", as it lies within the image footprint.'.
                    format(outlier_bases[i]))

        out.close()

        if os.path.exists(outlierfile):
            logger.info("Outlier file '{0}' written.".format(outlierfile))
        else:
            logger.error(
                "Outlier file '{0}' doesn't exist, so self-calibration loop {1} failed. Will terminate selfcal process."
                .format(outlierfile, loop))
            sys.exit(1)

        if num_outliers > 10:
            logger.warning(
                'The number of outliers written to "{0}" is > 10. As this will take some time to image, you may want to set a higher outlier_threshold than {1}, and/or increase your imsize beyond {2}.'
                .format(outlierfile, orig_threshold, imsize))

    return rmsfile, outlierfile
Пример #13
0
for i, item in enumerate(list_of_border_source_ids):
    if i == len(list_of_border_source_ids) - 1:
        continue
    QUERIES.append(
        query %
        (list_of_border_source_ids[i], list_of_border_source_ids[i + 1] - 1))

t00 = time.time()

os.system("mkdir Gaia_Healpix_{:d}".format(hpx_query))

for i in range(11654, nhpx):
    try:
        t0 = time.time()
        print(i, nhpx)
        job = gaia.launch_job_async(QUERIES[i])
        print(i, job)
        r = job.get_results()
        print(len(r))
        np.save(
            './Gaia_Healpix_{:d}/lvl{:d}_{:06d}.npy'.format(
                hpx_query, hpx_query, i), r)
        lst = gaia.list_async_jobs(verbose=True)
        for i2 in lst:
            gaia.remove_jobs(i2.jobid)
        t1 = time.time()
        print(
            "########################################################################################################################"
        )
        print(
            "Finished query {:6d} of {:6d}. Duration: {:.2f} s    Total passed time: {:.1f} s Estimate for completion: {:.1f}s "
Пример #14
0
    def test_start_job(self):
        connHandler = DummyConnHandler()
        tap = TapPlus("http://test:1111/tap", connhandler=connHandler)
        jobid = '12345'
        # Phase POST response
        responsePhase = DummyResponse()
        responsePhase.set_status_code(200)
        responsePhase.set_message("OK")
        responsePhase.set_data(method='POST',
                               context=None,
                               body=None,
                               headers=None)
        req = "async/" + jobid + "/phase?PHASE=RUN"
        connHandler.set_response(req, responsePhase)
        # Launch response
        responseLaunchJob = DummyResponse()
        responseLaunchJob.set_status_code(303)
        responseLaunchJob.set_message("OK")
        # list of list (httplib implementation for headers in response)
        launchResponseHeaders = [[
            'location', 'http://test:1111/tap/async/' + jobid
        ]]
        responseLaunchJob.set_data(method='POST',
                                   context=None,
                                   body=None,
                                   headers=launchResponseHeaders)
        query = 'query'
        dictTmp = {
            "REQUEST": "doQuery",
            "LANG": "ADQL",
            "FORMAT": "votable",
            "tapclient": str(TAP_CLIENT_ID),
            "QUERY": str(query)
        }
        sortedKey = taputils.taputil_create_sorted_dict_key(dictTmp)
        req = "async?" + sortedKey
        connHandler.set_response(req, responseLaunchJob)
        # Phase response
        responsePhase = DummyResponse()
        responsePhase.set_status_code(200)
        responsePhase.set_message("OK")
        responsePhase.set_data(method='GET',
                               context=None,
                               body="COMPLETED",
                               headers=None)
        req = "async/" + jobid + "/phase"
        connHandler.set_response(req, responsePhase)
        # Results response
        responseResultsJob = DummyResponse()
        responseResultsJob.set_status_code(200)
        responseResultsJob.set_message("OK")
        jobDataFile = data_path('job_1.vot')
        jobData = utils.read_file_content(jobDataFile)
        responseResultsJob.set_data(method='GET',
                                    context=None,
                                    body=jobData,
                                    headers=None)
        req = "async/" + jobid + "/results/result"
        connHandler.set_response(req, responseResultsJob)

        responseResultsJob.set_status_code(200)
        responseResultsJob.set_message("OK")
        job = tap.launch_job_async(query, autorun=False)
        assert job is not None, "Expected a valid job"
        assert job.get_phase() == 'PENDING', \
            "Wrong job phase. Expected: %s, found %s" % \
            ('PENDING', job.get_phase())
        # start job
        job.start()
        assert job.get_phase() == 'QUEUED', \
            "Wrong job phase. Expected: %s, found %s" % \
            ('QUEUED', job.get_phase())
        # results
        results = job.get_results()
        assert len(results) == 3, \
            "Wrong job results (num rows). Expected: %d, found %d" % \
            (3, len(results))
        assert job.get_phase() == 'COMPLETED', \
            "Wrong job phase. Expected: %s, found %s" % \
            ('COMPLETED', job.get_phase())
        # try to start again
        with pytest.raises(Exception):
            job.start()
Пример #15
0
    def ir_query(self, ircat_name, view_adql=True):
        """
        Performs a TAP+ query to irsa.ipac and returns the results.

        Main reason for this function is to have basis for easily incorporating TAP queries in a general query function later.
        -----------------------

        Example catalogs:

        "allwise_p3as_psd": AllWISE Source Catalog

        "fp_psc": 2MASS Point Source Catalog

        "glimpse_s07": GLIMPSE I Spring 07 Catalog (Spitzer)

        "cosmos_phot": COSMOS Photometry Catalog

        "iraspsc": IRAS Point Source Catalog

        -----------------------

        Arguments:
            ircat_name [string]: name of the catalogue in the irsa.ipac TAP spec
            view_adql [bool]: If True, prints the adql of the query generated.

        Returns:
            CatalogTable with query results.
        """

        catalogs = {
            "allwise": "allwise_p3as_psd",
            "tmass": "fp_psc",
            "glimpse": "glimpse_s07"
        }

        catalog = catalogs[ircat_name]

        if ircat_name == "tmass":
            cols = tmass_cols
            cols_list = tmass_cols_list

        if ircat_name == "allwise":
            cols = allwise_cols
            cols_list = allwise_cols_list

        search_string = "SELECT {} FROM {} WHERE CONTAINS(POINT('ICRS',ra,dec),CIRCLE('ICRS',{},{},{}))=1 ".format(
            cols, catalog, str(self.skycoord.ra.degree),
            str(self.skycoord.dec.degree), self.radius)

        if view_adql:
            out(search_string)

        ipac = TapPlus(url="https://irsa.ipac.caltech.edu/TAP/")

        out("Creating query...")
        job = ipac.launch_job_async(search_string)

        out("Retrieving results...")
        query_results = job.get_results()

        for old, new in zip(query_results.colnames, cols_list):
            query_results.rename_column(old, new)

        out("Results retrieved.")

        print(query_results.colnames)

        #info_out(str(len(query_results['designation'])) + " sources detected.")

        # Write query results to file.
        fname = tpath + "/" + ircat_name + "_query.dat"
        query_results.write(fname, format='ascii.ecsv')

        return (CatalogTable([ircat_name], query_results))
Пример #16
0
def fs_table_conequery(args):

    import numpy as np
    import pandas as pd
    import math
    import time
    import datetime
    from astroquery.utils.tap.core import TapPlus

    if args.verbose > 0:
        print
        print '* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *'
        print 'fs_table_conequery'
        print '* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *'
        print

    print datetime.datetime.now()

    # Extract info from argument list...
    radeg0 = args.radeg
    decdeg0 = args.decdeg
    radiusdeg = args.radiusdeg
    outputFile = args.outputFile

    # Read in nobs_fs_file...
    nobs_fs_file = 'nobs_fs_table.csv'
    df_nobs_fs = pd.read_csv(nobs_fs_file)

    # Read in images_file...
    images_file = 'images_table.csv'
    df_images = pd.read_csv(images_file)

    # Merge df_nobs_fs and df_images on image_id...
    df_images_nobs = df_nobs_fs.merge(df_images, on=['image_id']).sort_values(
        by='image_id', ascending=True).reset_index(drop=True)

    # Calculate separation between center of cone
    # and ra,dec of each image in df_images_nobs
    rarad0 = math.radians(radeg0)
    decrad0 = math.radians(decdeg0)

    df_images_nobs.loc[:, 'rarad'] = np.radians(df_images_nobs.loc[:, 'ra'])
    df_images_nobs.loc[:, 'declrad'] = np.radians(df_images_nobs.loc[:,
                                                                     'decl'])

    df_images_nobs.loc[:,'cosSep'] = math.sin(decrad0)*np.sin(df_images_nobs.loc[:,'declrad']) + \
        math.cos(decrad0)*np.cos(df_images_nobs.loc[:,'declrad'])*np.cos(rarad0 - df_images_nobs.loc[:,'rarad'])
    df_images_nobs.loc[:, 'sepDeg'] = np.degrees(
        np.arccos(df_images_nobs.loc[:, 'cosSep']))

    # Find which image_id's lie within the cone search radius...
    mask = (df_images_nobs.loc[:, 'sepDeg'] < radiusdeg)
    if args.verbose > 0:
        print df_images_nobs.loc[
            mask, ['image_id', 'filter', 'ra', 'decl', 'sepDeg']]

    # Establish TAP connection to SkyMapper database...
    skymapper = TapPlus(url="http://skymappertap.asvo.nci.org.au/ncitap/tap")

    # Loop over image_id's...
    i = 0
    for image_id in df_images_nobs.loc[mask, 'image_id']:

        # Formulate the query...
        query = """SELECT * FROM dr1.fs_photometry where image_id=%d""" % (
            image_id)
        if args.verbose > 0:
            print "Query:  ", query

        # Submit the query as an asynchronous job...
        if args.verbose > 0:
            print "Query start:      ", datetime.datetime.now()
        job = skymapper.launch_job_async(query)
        if args.verbose > 0:
            print "Query completed:  ", datetime.datetime.now()

        # Retrieve the results as an astropy Table...
        if args.verbose > 0:
            print "Retrieval start:      ", datetime.datetime.now()
        fs_table = job.get_results()
        if args.verbose > 0:
            print "Retrieval completed:  ", datetime.datetime.now()

        # Sort table by ra_img
        # fs_table.sort('ra_img')

        # "Append" does not seem to work for stropy table.write.
        # For now, save each file individually....
        # Save table to outputFile...
        #if args.verbose>0:
        #    print "File output start:      ", datetime.datetime.now()
        #if i == 0:
        #    fs_table.write(outputFile)
        #else:
        #    fs_table.write(outputFile, append=True)
        #if args.verbose>0:
        #    print "File output completed:  ", datetime.datetime.now()
        tmpOutputFile = """%s.%d.csv""" % (outputFile, image_id)
        if args.verbose > 0:
            print "File output start:      ", datetime.datetime.now()
        fs_table.write(tmpOutputFile)
        if args.verbose > 0:
            print "File output completed:  ", datetime.datetime.now()

        i = i + 1

        if args.verbose > 0: print

    return 0
Пример #17
0
def test_launch_async_job():
    connHandler = DummyConnHandler()
    tap = TapPlus("http://test:1111/tap", connhandler=connHandler)
    jobid = '12345'
    # Launch response
    responseLaunchJob = DummyResponse()
    responseLaunchJob.set_status_code(500)
    responseLaunchJob.set_message("ERROR")
    # list of list (httplib implementation for headers in response)
    launchResponseHeaders = [[
        'location', f'http://test:1111/tap/async/{jobid}'
    ]]
    responseLaunchJob.set_data(method='POST',
                               context=None,
                               body=None,
                               headers=launchResponseHeaders)
    query = 'query'
    dictTmp = {
        "REQUEST": "doQuery",
        "LANG": "ADQL",
        "FORMAT": "votable",
        "tapclient": str(TAP_CLIENT_ID),
        "PHASE": "RUN",
        "QUERY": str(query)
    }
    sortedKey = taputils.taputil_create_sorted_dict_key(dictTmp)
    req = f"async?{sortedKey}"
    connHandler.set_response(req, responseLaunchJob)
    # Phase response
    responsePhase = DummyResponse()
    responsePhase.set_status_code(500)
    responsePhase.set_message("ERROR")
    responsePhase.set_data(method='GET',
                           context=None,
                           body="COMPLETED",
                           headers=None)
    req = f"async/{jobid}/phase"
    connHandler.set_response(req, responsePhase)
    # Results response
    responseResultsJob = DummyResponse()
    responseResultsJob.set_status_code(500)
    responseResultsJob.set_message("ERROR")
    jobDataFile = data_path('job_1.vot')
    jobData = utils.read_file_content(jobDataFile)
    responseResultsJob.set_data(method='GET',
                                context=None,
                                body=jobData,
                                headers=None)
    req = f"async/{jobid}/results/result"
    connHandler.set_response(req, responseResultsJob)

    with pytest.raises(Exception):
        tap.launch_job_async(query)

    responseLaunchJob.set_status_code(303)
    responseLaunchJob.set_message("OK")
    with pytest.raises(Exception):
        tap.launch_job_async(query)

    responsePhase.set_status_code(200)
    responsePhase.set_message("OK")
    with pytest.raises(Exception):
        tap.launch_job_async(query)

    responseResultsJob.set_status_code(200)
    responseResultsJob.set_message("OK")
    job = tap.launch_job_async(query)
    assert job is not None
    assert job.async_ is True
    assert job.get_phase() == 'COMPLETED'
    assert job.failed is False

    # results
    results = job.get_results()
    assert len(results) == 3
    __check_results_column(results, 'alpha', 'alpha', None, np.float64)
    __check_results_column(results, 'delta', 'delta', None, np.float64)
    __check_results_column(results, 'source_id', 'source_id', None, object)
    __check_results_column(results, 'table1_oid', 'table1_oid', None, np.int32)
Пример #18
0
def test_job_parameters():
    connHandler = DummyConnHandler()
    tap = TapPlus("http://test:1111/tap", connhandler=connHandler)
    jobid = '12345'
    # Launch response
    responseLaunchJob = DummyResponse()
    responseLaunchJob.set_status_code(303)
    responseLaunchJob.set_message("OK")
    # list of list (httplib implementation for headers in response)
    launchResponseHeaders = [[
        'location', f'http://test:1111/tap/async/{jobid}'
    ]]
    responseLaunchJob.set_data(method='POST',
                               context=None,
                               body=None,
                               headers=launchResponseHeaders)
    query = 'query'
    dictTmp = {
        "REQUEST": "doQuery",
        "LANG": "ADQL",
        "FORMAT": "votable",
        "tapclient": str(TAP_CLIENT_ID),
        "QUERY": str(query)
    }
    sortedKey = taputils.taputil_create_sorted_dict_key(dictTmp)
    req = f"async?{sortedKey}"
    connHandler.set_response(req, responseLaunchJob)
    # Phase response
    responsePhase = DummyResponse()
    responsePhase.set_status_code(200)
    responsePhase.set_message("OK")
    responsePhase.set_data(method='GET',
                           context=None,
                           body="COMPLETED",
                           headers=None)
    req = f"async/{jobid}/phase"
    connHandler.set_response(req, responsePhase)
    # Results response
    responseResultsJob = DummyResponse()
    responseResultsJob.set_status_code(200)
    responseResultsJob.set_message("OK")
    jobDataFile = data_path('job_1.vot')
    jobData = utils.read_file_content(jobDataFile)
    responseResultsJob.set_data(method='GET',
                                context=None,
                                body=jobData,
                                headers=None)
    req = f"async/{jobid}/results/result"
    connHandler.set_response(req, responseResultsJob)

    responseResultsJob.set_status_code(200)
    responseResultsJob.set_message("OK")
    job = tap.launch_job_async(query, autorun=False)
    assert job is not None
    assert job.get_phase() == 'PENDING'

    # parameter response
    responseParameters = DummyResponse()
    responseParameters.set_status_code(200)
    responseParameters.set_message("OK")
    responseParameters.set_data(method='GET',
                                context=None,
                                body=None,
                                headers=None)
    req = f"async/{jobid}?param1=value1"
    connHandler.set_response(req, responseParameters)
    # Phase POST response
    responsePhase = DummyResponse()
    responsePhase.set_status_code(200)
    responsePhase.set_message("OK")
    responsePhase.set_data(method='POST',
                           context=None,
                           body=None,
                           headers=None)
    req = f"async/{jobid}/phase?PHASE=RUN"
    connHandler.set_response(req, responsePhase)

    # send parameter OK
    job.send_parameter("param1", "value1")
    # start job
    job.start()
    assert job.get_phase() == 'QUEUED'
    # try to send a parameter after execution
    with pytest.raises(Exception):
        job.send_parameter("param2", "value2")
Пример #19
0
    def test_launc_async_job(self):
        connHandler = DummyConnHandler()
        tap = TapPlus("http://test:1111/tap", connhandler=connHandler)
        jobid = '12345'
        # Launch response
        responseLaunchJob = DummyResponse()
        responseLaunchJob.set_status_code(500)
        responseLaunchJob.set_message("ERROR")
        # list of list (httplib implementation for headers in response)
        launchResponseHeaders = [
            ['location', 'http://test:1111/tap/async/' + jobid]
            ]
        responseLaunchJob.set_data(method='POST',
                                   context=None,
                                   body=None,
                                   headers=launchResponseHeaders)
        query = 'query'
        dictTmp = {
            "REQUEST": "doQuery",
            "LANG": "ADQL",
            "FORMAT": "votable",
            "tapclient": str(TAP_CLIENT_ID),
            "PHASE": "RUN",
            "QUERY": str(query)}
        sortedKey = taputils.taputil_create_sorted_dict_key(dictTmp)
        req = "async?" + sortedKey
        connHandler.set_response(req, responseLaunchJob)
        # Phase response
        responsePhase = DummyResponse()
        responsePhase.set_status_code(500)
        responsePhase.set_message("ERROR")
        responsePhase.set_data(method='GET',
                               context=None,
                               body="COMPLETED",
                               headers=None)
        req = "async/" + jobid + "/phase"
        connHandler.set_response(req, responsePhase)
        # Results response
        responseResultsJob = DummyResponse()
        responseResultsJob.set_status_code(500)
        responseResultsJob.set_message("ERROR")
        jobDataFile = data_path('job_1.vot')
        jobData = utils.read_file_content(jobDataFile)
        responseResultsJob.set_data(method='GET',
                                    context=None,
                                    body=jobData,
                                    headers=None)
        req = "async/" + jobid + "/results/result"
        connHandler.set_response(req, responseResultsJob)

        with pytest.raises(Exception):
            tap.launch_job_async(query)

        responseLaunchJob.set_status_code(303)
        responseLaunchJob.set_message("OK")
        with pytest.raises(Exception):
            tap.launch_job_async(query)

        responsePhase.set_status_code(200)
        responsePhase.set_message("OK")
        with pytest.raises(Exception):
            tap.launch_job_async(query)

        responseResultsJob.set_status_code(200)
        responseResultsJob.set_message("OK")
        job = tap.launch_job_async(query)
        assert job is not None, "Expected a valid job"
        assert job.is_sync() is False, "Expected an asynchronous job"
        assert job.get_phase() == 'COMPLETED', \
            "Wrong job phase. Expected: %s, found %s" % \
            ('COMPLETED', job.get_phase())
        assert job.is_failed() is False, "Wrong job status (set Failed = True)"
        # results
        results = job.get_results()
        assert len(results) == 3, \
            "Wrong job results (num rows). Expected: %d, found %d" % \
            (3, len(results))
        self.__check_results_column(results,
                                    'alpha',
                                    'alpha',
                                    None,
                                    np.float64)
        self.__check_results_column(results,
                                    'delta',
                                    'delta',
                                    None,
                                    np.float64)
        self.__check_results_column(results,
                                    'source_id',
                                    'source_id',
                                    None,
                                    np.object)
        self.__check_results_column(results,
                                    'table1_oid',
                                    'table1_oid',
                                    None,
                                    np.int32)
Пример #20
0
tables = tap.load_tables()

# We have to find the name of the Gaia DR2 table in the Vizier database.

# In[14]:

for t in tables:
    if 'gaia' in t.name:
        print(t.name)

# We now cross-match to LAMOST find Gaia stars within 1 arcsec (1/3600=0.00027777) of each LAMOST star.

# In[21]:

job = tap.launch_job_async(
    'select top 10 * from "I/345/gaia2" as gaia, ' + '"V/153/dr4" as lamost ' +
    "where 1=CONTAINS(POINT('ICRS',gaia.ra,gaia.dec)," +
    "CIRCLE('ICRS',lamost.raj2000,lamost.dej2000,0.00027777))")
tableV = job.get_results()
print(tableV)

# In[22]:

tableV[['ObsID', 'RAJ2000', 'ra']]

# ## Gaia RVS selection function

# One other unique function provided in the Gaia archive is gaia_healpix_index which gives the healpix number of each Gaia source. Healpix are a method of dividing up the sphere into equal area pixels. This is useful as we can bin the catalogue by Healpix. In the following we count all sources in bins of G and healpix for a small region on the sky.

# In[27]:

from astroquery.gaia import Gaia