示例#1
0
def run(input_file, c, meta):
    p = HypatiaExoParser(input_file, meta['normalization'])
    if c:
        for star, elements, planets in p.next():
            try:
                star.upsert(c)
                logger.info('Saved star, "%s"\n', star.columns['hip'])
                for catalogue, composition in elements:
                    # Assumption 251024: Because of the way the records are updated, if a catalogue is updated say
                    # from 'FeH 0.3 [Adamow et al. (2015)]' to 'FeH 0.3 [Adamow et al. (2016)]' a new catalogue is
                    # added and the particular composition for that catalogue will still be present with
                    # old catalogue in the composition table. For the above example the table composition will have
                    # 2 entries, one with 2015 catalogue and one with 2016
                    # Fix: Delete the star completely and add it again. Deleting a star, also deletes the corresponding
                    # composition elements, but catalogues are retained as other stars may still use it!

                    cid = catalogue.upsert(c)
                    composition.set('hip', star.columns['hip'])
                    composition.set('cid', cid)
                    composition.upsert(c)
                for planet in planets:
                    planet.set('hip', star.columns['hip'])
                    planet.upsert(c)
            except:
                logger.exception('Saving star failed: "%s"',
                                 star.columns['hip'])
        c.close()
def planet_props():
    """
    **** DEPRECATED: Use /planets/ instead ****

    Retrieve planet properties
    POST BODY:
    {
        properties: [optional] one or more of properties of a planet, e.g. [name, mass, hip, p, e, a]
        stars: [required] a list of hips whose planets' properties are returned
    }
    where,
    mass => planet mass
    if properties are ignored, all properties are returned
    :return: {hip1_planet1: {m_p: 867, p: 0.889}, hip2_planet2: {m_p: 773, p: 0.8772}}
    """
    try:
        stars = map(lambda s: s.strip(), request.json['stars'])
        props = map(lambda s: s.strip(), request.json.get('properties', Planet.DEFAULTS.keys()))
        props_cols_map = {'name': 'name', 'mass': 'm_p as mass', 'p': 'p', 'e': 'e', 'a': 'a'}
        columns = [props_cols_map.get(p, p) for p in props]
        query = """SELECT
                      CONCAT(s.hip, ' [', p.name, ']') as star_planet, {}
                    FROM planet p
                    INNER JOIN star s
                      ON s.hip = p.hip
                    WHERE s.hip IN (%s)""".format(', '.join(columns))
        resp = tuples_as_dict(query, stars, 0)
        return jsonify({'planets': resp, "status": {"message": "Fetched info for %s planets" % len(resp)}})
    except Exception as err:
        logger.exception(err)
        return jsonify({"status": {"message": "Something went wrong"}}), 500
示例#3
0
def stars(page, limit):
    """
    Retrieve requested number of stars of a given page satisfying a condition
    :param page: page number
    :param limit: number of stars in this page
    :return:
    """
    try:
        # TODO: Possible SQL injection due to WHERE clause
        query = "SELECT * FROM star WHERE {} ORDER BY `hip` LIMIT %s OFFSET %s".format(
            request.args.get("query") or "1 = 1")
        db_res = MySQL.execute(DATABASE, query, [limit, page * limit])
        index_of_hip = db_res['columns'].index('hip')
        resp = {
            row[index_of_hip]: dict(
                zip(db_res['columns'],
                    [str(t) if type(t) is bytearray else t for t in row]))
            for row in db_res['rows']
        }
        return jsonify({
            'stars': resp,
            "status": {
                "message": "Fetched %s stars" % (len(resp), )
            }
        })
    except Exception as err:
        logger.exception(err)
        return jsonify({"status": {"message": "Something went wrong"}}), 500
def run(input_file, c, meta):
    p = HypatiaExoParser(input_file, meta['normalization'])
    if c:
        for star, elements, planets in p.next():
            try:
                star.upsert(c)
                logger.info('Saved star, "%s"\n', star.columns['hip'])
                for catalogue, composition in elements:
                    # Assumption 251024: Because of the way the records are updated, if a catalogue is updated say
                    # from 'FeH 0.3 [Adamow et al. (2015)]' to 'FeH 0.3 [Adamow et al. (2016)]' a new catalogue is
                    # added and the particular composition for that catalogue will still be present with
                    # old catalogue in the composition table. For the above example the table composition will have
                    # 2 entries, one with 2015 catalogue and one with 2016
                    # Fix: Delete the star completely and add it again. Deleting a star, also deletes the corresponding
                    # composition elements, but catalogues are retained as other stars may still use it!

                    cid = catalogue.upsert(c)
                    composition.set('hip', star.columns['hip'])
                    composition.set('cid', cid)
                    composition.upsert(c)
                for planet in planets:
                    planet.set('hip', star.columns['hip'])
                    planet.upsert(c)
            except:
                logger.exception('Saving star failed: "%s"', star.columns['hip'])
        c.close()
示例#5
0
def composition_scatter():
    """
    Median composition of requested elements for the requested star considering common catalogs
    POST BODY:
    {
        normalization: [required] the type of solar normalization
        stars: [required] comma separated list of hips
        elements: [required] comma separated list of elements for which compositions are required
        catalogs: [optional] comma separated list of catalogs (author_year column) to exclude if provided, else all will be used
    }
    :return: {hip1: {FeH: {mdn: 0.5, avg: 0.56}, OH: {mdn: -0.07, avg: 0}, ...}, {hip2: {FeH: {mdn: 0.09, avg: 0.1}, ...}}
    """
    try:
        solarnorm = request.json['normalization']
        stars = map(lambda s: s.strip(), request.json['stars'])
        elements = map(lambda e: e.strip(), request.json['elements'])
        catalogs = map(lambda c: c.strip(), request.json.get('catalogs', []))
        query = """SELECT
                      t1.hip,
                      t1.cid,
                      t1.element,
                      t1.value
                    FROM composition t1, catalogue c, composition t2
                      WHERE t1.solarnorm = '%s' AND t2.solarnorm = '%s'
                      AND t1.cid = t2.cid
                      AND t1.element <> t2.element
                      AND t1.hip = t2.hip
                      AND t1.hip IN (%s)
                      AND t1.element IN (%s)
                      AND t2.element IN (%s)
                      AND t1.cid = c.id %s;"""
        in_str_stars = ','.join(['%s'] * len(stars))
        in_str_elems = ','.join(['%s'] * len(elements))
        in_str_cats = ','.join(['%s'] * len(catalogs))
        catalog_query = 'AND c.author_year NOT IN (%s)' % in_str_cats if len(
            catalogs) > 0 else ''
        db_res = MySQL.execute(
            DATABASE, query % (solarnorm, solarnorm, in_str_stars,
                               in_str_elems, in_str_elems, catalog_query),
            stars + elements + elements + catalogs)

        resp = {}
        for row in db_res['rows']:
            upsert_dict_arr(resp, row[0], row[2], row[3])
        for star in resp:
            for e in resp[star]:
                resp[star][e] = {
                    'mdn': median(resp[star][e]),
                    'avg': mean(resp[star][e])
                }
        return jsonify({
            'stars': resp,
            "status": {
                "message": "Fetched %s stars" % len(resp)
            }
        })
    except Exception as err:
        logger.exception(err)
        return jsonify({"status": {"message": "Something went wrong"}}), 500
def elements_of_star(hip):
    """
    Fetches the elements of a star
    :param hip: hip of the star
    :return:
    """
    try:
        query = "SELECT DISTINCT element FROM composition WHERE hip = %s"
        res = map(lambda e: e[0], MySQL.execute(DATABASE, query, [hip])['rows'])
        return jsonify({'elements': res})
    except Exception as err:
        logger.exception(err)
        return jsonify({"status": {"message": "Something went wrong"}}), 500
示例#7
0
def elements_of_star(hip):
    """
    Fetches the elements of a star
    :param hip: hip of the star
    :return:
    """
    try:
        query = "SELECT DISTINCT element FROM composition WHERE hip = %s"
        res = map(lambda e: e[0],
                  MySQL.execute(DATABASE, query, [hip])['rows'])
        return jsonify({'elements': res})
    except Exception as err:
        logger.exception(err)
        return jsonify({"status": {"message": "Something went wrong"}}), 500
def composition_scatter():
    """
    Median composition of requested elements for the requested star considering common catalogs
    POST BODY:
    {
        normalization: [required] the type of solar normalization
        stars: [required] comma separated list of hips
        elements: [required] comma separated list of elements for which compositions are required
        catalogs: [optional] comma separated list of catalogs (author_year column) to exclude if provided, else all will be used
    }
    :return: {hip1: {FeH: {mdn: 0.5, avg: 0.56}, OH: {mdn: -0.07, avg: 0}, ...}, {hip2: {FeH: {mdn: 0.09, avg: 0.1}, ...}}
    """
    try:
        solarnorm = request.json['normalization']
        stars = map(lambda s: s.strip(), request.json['stars'])
        elements = map(lambda e: e.strip(), request.json['elements'])
        catalogs = map(lambda c: c.strip(), request.json.get('catalogs', []))
        query = """SELECT
                      t1.hip,
                      t1.cid,
                      t1.element,
                      t1.value
                    FROM composition t1, catalogue c, composition t2
                      WHERE t1.solarnorm = '%s' AND t2.solarnorm = '%s'
                      AND t1.cid = t2.cid
                      AND t1.element <> t2.element
                      AND t1.hip = t2.hip
                      AND t1.hip IN (%s)
                      AND t1.element IN (%s)
                      AND t2.element IN (%s)
                      AND t1.cid = c.id %s;"""
        in_str_stars = ','.join(['%s'] * len(stars))
        in_str_elems = ','.join(['%s'] * len(elements))
        in_str_cats = ','.join(['%s'] * len(catalogs))
        catalog_query = 'AND c.author_year NOT IN (%s)' % in_str_cats if len(catalogs) > 0 else ''
        db_res = MySQL.execute(DATABASE, query % (solarnorm, solarnorm, in_str_stars, in_str_elems, in_str_elems,
                                                  catalog_query), stars + elements + elements + catalogs)

        resp = {}
        for row in db_res['rows']:
            upsert_dict_arr(resp, row[0], row[2], row[3])
        for star in resp:
            for e in resp[star]:
                resp[star][e] = {'mdn': median(resp[star][e]), 'avg': mean(resp[star][e])}
        return jsonify({'stars': resp, "status": {"message": "Fetched %s stars" % len(resp)}})
    except Exception as err:
        logger.exception(err)
        return jsonify({"status": {"message": "Something went wrong"}}), 500
def stars(page, limit):
    """
    Retrieve requested number of stars of a given page satisfying a condition
    :param page: page number
    :param limit: number of stars in this page
    :return:
    """
    try:
        # TODO: Possible SQL injection due to WHERE clause
        query = "SELECT * FROM star WHERE {} ORDER BY `hip` LIMIT %s OFFSET %s".format(
            request.args.get("query") or "1 = 1")
        db_res = MySQL.execute(DATABASE, query, [limit, page * limit])
        index_of_hip = db_res['columns'].index('hip')
        resp = {row[index_of_hip]: dict(zip(db_res['columns'], [str(t) if type(t) is bytearray else t for t in row]))
                for row in db_res['rows']}
        return jsonify({'stars': resp, "status": {"message": "Fetched %s stars" % (len(resp),)}})
    except Exception as err:
        logger.exception(err)
        return jsonify({"status": {"message": "Something went wrong"}}), 500
示例#10
0
def planet_props():
    """
    **** DEPRECATED: Use /planets/ instead ****

    Retrieve planet properties
    POST BODY:
    {
        properties: [optional] one or more of properties of a planet, e.g. [name, mass, hip, p, e, a]
        stars: [required] a list of hips whose planets' properties are returned
    }
    where,
    mass => planet mass
    if properties are ignored, all properties are returned
    :return: {hip1_planet1: {m_p: 867, p: 0.889}, hip2_planet2: {m_p: 773, p: 0.8772}}
    """
    try:
        stars = map(lambda s: s.strip(), request.json['stars'])
        props = map(lambda s: s.strip(),
                    request.json.get('properties', Planet.DEFAULTS.keys()))
        props_cols_map = {
            'name': 'name',
            'mass': 'm_p as mass',
            'p': 'p',
            'e': 'e',
            'a': 'a'
        }
        columns = [props_cols_map.get(p, p) for p in props]
        query = """SELECT
                      CONCAT(s.hip, ' [', p.name, ']') as star_planet, {}
                    FROM planet p
                    INNER JOIN star s
                      ON s.hip = p.hip
                    WHERE s.hip IN (%s)""".format(', '.join(columns))
        resp = tuples_as_dict(query, stars, 0)
        return jsonify({
            'planets': resp,
            "status": {
                "message": "Fetched info for %s planets" % len(resp)
            }
        })
    except Exception as err:
        logger.exception(err)
        return jsonify({"status": {"message": "Something went wrong"}}), 500
def compositions_of_star(hip):
    """
    Retrieves composition of a star
    If an element has multiple values from different catalogs, average value is returned
    :param hip: hip of the star
    :return: {FeH: 0.5, OH: -0.6}
    """
    try:
        elements = request.args.getlist('elements')
        in_clause = ','.join(['%s'] * len(elements))
        query = """SELECT element, AVG(value)
                    FROM composition WHERE hip = %s AND element IN ({})
                    GROUP BY element;""".format(in_clause)
        res = {}
        for k, v in MySQL.execute(DATABASE, query, [hip] + elements)['rows']:
            res[k] = v
        return jsonify(res)
    except Exception as err:
        logger.exception(err)
        return jsonify({"status": {"message": "Something went wrong"}}), 500
示例#12
0
def compositions_of_star(hip):
    """
    Retrieves composition of a star
    If an element has multiple values from different catalogs, average value is returned
    :param hip: hip of the star
    :return: {FeH: 0.5, OH: -0.6}
    """
    try:
        elements = request.args.getlist('elements')
        in_clause = ','.join(['%s'] * len(elements))
        query = """SELECT element, AVG(value)
                    FROM composition WHERE hip = %s AND element IN ({})
                    GROUP BY element;""".format(in_clause)
        res = {}
        for k, v in MySQL.execute(DATABASE, query, [hip] + elements)['rows']:
            res[k] = v
        return jsonify(res)
    except Exception as err:
        logger.exception(err)
        return jsonify({"status": {"message": "Something went wrong"}}), 500
示例#13
0
def stellar_props():
    """
    Retrieve stellar properties
    POST BODY:
    {
        properties: [optional] one or more of properties of a star, e.g. [u, w, dist, v, mass]
        stars: [required] a list of hips for whose the above properties are required
    }
    where,
    mass => stellar mass
    if properties are ignored, all properties are returned
    :return: {hip1: {mass: 867, dist: 0.889}, hip2: {mass: 773, dist: 0.8772}}
    """
    try:
        stars = map(lambda s: s.strip(), request.json['stars'])
        props = map(lambda s: s.strip(),
                    request.json.get('properties', Star.DEFAULTS.keys()))
        props_cols_map = {
            'u': 'u',
            'w': 'w',
            'dist': 'dist',
            'v': 'v',
            'mass': 'mass'
        }
        columns = [props_cols_map.get(p, p) for p in props]
        query = "SELECT hip, {} FROM star WHERE hip IN (%s);".format(
            ', '.join(columns))
        resp = tuples_as_dict(query, stars, 0)
        return jsonify({
            'stars': resp,
            "status": {
                "message": "Fetched info for %s stars" % len(resp)
            }
        })
    except Exception as err:
        logger.exception(err)
        return jsonify({"status": {"message": "Something went wrong"}}), 500
def stellar_props():
    """
    Retrieve stellar properties
    POST BODY:
    {
        properties: [optional] one or more of properties of a star, e.g. [u, w, dist, v, mass]
        stars: [required] a list of hips for whose the above properties are required
    }
    where,
    mass => stellar mass
    if properties are ignored, all properties are returned
    :return: {hip1: {mass: 867, dist: 0.889}, hip2: {mass: 773, dist: 0.8772}}
    """
    try:
        stars = map(lambda s: s.strip(), request.json['stars'])
        props = map(lambda s: s.strip(), request.json.get('properties', Star.DEFAULTS.keys()))
        props_cols_map = {'u': 'u', 'w': 'w', 'dist': 'dist', 'v': 'v', 'mass': 'mass'}
        columns = [props_cols_map.get(p, p) for p in props]
        query = "SELECT hip, {} FROM star WHERE hip IN (%s);".format(', '.join(columns))
        resp = tuples_as_dict(query, stars, 0)
        return jsonify({'stars': resp, "status": {"message": "Fetched info for %s stars" % len(resp)}})
    except Exception as err:
        logger.exception(err)
        return jsonify({"status": {"message": "Something went wrong"}}), 500