def mongify(_dict): """Massage a TNS catalog entry into something digestable by mongo :param _dict: :return: """ _tmp = dict(_dict) doc = { _key.lower().replace(".", "_").replace(" ", "_"): _tmp[_key].strip() if isinstance(_tmp[_key], str) else _tmp[_key] for _key in _tmp if not pd.isnull(_tmp[_key]) } doc["_id"] = _dict["ID"] doc.pop("id") # discovery date as datetime try: doc["discovery_date"] = datetime.datetime.strptime( _dict["Discovery Date (UT)"], "%Y-%m-%d %H:%M:%S.%f").astimezone(pytz.utc) except Exception as _e: log(_e) try: doc["discovery_date"] = datetime.datetime.strptime( _dict["Discovery Date (UT)"], "%Y-%m-%d %H:%M:%S").astimezone(pytz.utc) except Exception as _e: log(_e) doc["discovery_date"] = None # GeoJSON for 2D indexing doc["coordinates"] = {} _ra_str = doc["ra"] _dec_str = doc["dec"] _radec_str = [_ra_str, _dec_str] _ra_geojson, _dec_geojson = radec_str2geojson(_ra_str, _dec_str) doc["coordinates"]["radec_str"] = _radec_str doc["coordinates"]["radec_geojson"] = { "type": "Point", "coordinates": [_ra_geojson, _dec_geojson], } return doc
def mongify(_dict): _tmp = dict(_dict) doc = { _key.lower().replace('.', '_').replace(' ', '_'): _tmp[_key] for _key in _tmp } # candid+objectId should be a unique combination: doc['_id'] = f"{_dict['ID']}" # discovery date as datetime try: doc['discovery_date'] = datetime.datetime.strptime( _dict['Discovery Date (UT)'], '%Y-%m-%d %H:%M:%S').astimezone(pytz.utc) except Exception as _e: doc['discovery_date'] = None # GeoJSON for 2D indexing doc['coordinates'] = {} # doc['coordinates']['epoch'] = 2000.0 _ra_str = doc['ra'] _dec_str = doc['dec'] _radec_str = [_ra_str, _dec_str] _ra_geojson, _dec_geojson = radec_str2geojson(_ra_str, _dec_str) doc['coordinates']['radec_str'] = _radec_str doc['coordinates']['radec_geojson'] = { 'type': 'Point', 'coordinates': [_ra_geojson, _dec_geojson] } # degrees: doc['coordinates']['radec_deg'] = [_ra_geojson + 180.0, _dec_geojson] # radians: doc['coordinates']['radec_rad'] = [(_ra_geojson + 180.0) * np.pi / 180.0, _dec_geojson * np.pi / 180.0] return doc
def mongify(doc): if doc['ra'] == -99. and doc['dec'] == -99.0: return doc # GeoJSON for 2D indexing doc['coordinates'] = {} # doc['coordinates']['epoch'] = 2000.0 _ra_str = doc['ra'] _dec_str = doc['dec'] _radec_str = [_ra_str, _dec_str] _ra_geojson, _dec_geojson = radec_str2geojson(_ra_str, _dec_str) doc['coordinates']['radec_str'] = _radec_str doc['coordinates']['radec_geojson'] = {'type': 'Point', 'coordinates': [_ra_geojson, _dec_geojson]} return doc
def mongify(doc): if doc["ra"] == -99.0 and doc["dec"] == -99.0: return doc # GeoJSON for 2D indexing doc["coordinates"] = dict() # doc['coordinates']['epoch'] = 2000.0 _ra_str = doc["ra"] _dec_str = doc["dec"] _radec_str = [_ra_str, _dec_str] _ra_geojson, _dec_geojson = radec_str2geojson(_ra_str, _dec_str) doc["coordinates"]["radec_str"] = _radec_str doc["coordinates"]["radec_geojson"] = { "type": "Point", "coordinates": [_ra_geojson, _dec_geojson], } return doc
def search(): """ Endpoint for the web GUI search page :return: """ if flask_login.current_user.is_anonymous: user_id = None access_token = None else: user_id = str(flask_login.current_user.id) if 'access_token' in flask.session: access_token = flask.session['access_token'] else: access_token = None # try: # print(flask.session) # print(flask.session['access_token']) # print(flask_login.current_user.id, flask_login.current_user.access_token) # except Exception as e: # print(e) # print(user_id) messages = [] # alerts = list(cursor) if cursor is not None else [] _alerts = [] # got a request? if flask.request.method == 'POST': try: form = flask.request.form # print(form) # convert to filter and projection to run a find() query with the API: query = {'filter': {}, 'projection': {}} objects = literal_eval(form['radec'].strip()) if isinstance(objects, list): object_coordinates = objects object_names = [str(obj_crd) for obj_crd in object_coordinates] elif isinstance(objects, dict): object_names, object_coordinates = zip(*objects.items()) object_names = list(map(str, object_names)) else: raise ValueError('Unsupported type of object coordinates') cone_search_radius = float(form['cone_search_radius']) # convert to rad: if form['cone_search_unit'] == 'arcsec': cone_search_radius *= np.pi / 180.0 / 3600. elif form['cone_search_unit'] == 'arcmin': cone_search_radius *= np.pi / 180.0 / 60. elif form['cone_search_unit'] == 'deg': cone_search_radius *= np.pi / 180.0 elif form['cone_search_unit'] == 'rad': cone_search_radius *= 1 else: raise Exception( 'Unknown cone search unit. Must be in [deg, rad, arcsec, arcmin]' ) # print(objects) # print(cone_search_radius) # get only programid=1 data for anonymous users: query['filter']['$and'] = [{ 'candidate.programid': { '$eq': 1 } }] if user_id is None else [] query['filter']['$and'].append({'$or': []}) for oi, obj_crd in enumerate(object_coordinates): # convert ra/dec into GeoJSON-friendly format # print(obj_crd) _ra, _dec = radec_str2geojson(*obj_crd) query['filter']['$and'][-1]['$or'].append({ 'coordinates.radec_geojson': { '$geoWithin': { '$centerSphere': [[_ra, _dec], cone_search_radius] } } }) # FIXME: remove once 'projection' is exposed: query['projection'] = { **query['projection'], **{ 'prv_candidates': 0, 'cutoutScience': 0, 'cutoutTemplate': 0, 'cutoutDifference': 0 } } # query own API: if access_token is not None: r = requests.post(os.path.join( 'http://', f"localhost:{config['server']['port']}", 'alerts'), json=query, headers={ 'Authorization': 'Bearer {:s}'.format(access_token) }) else: r = requests.post(os.path.join( 'http://', f"localhost:{config['server']['port']}", 'alerts'), json=query) _alerts = r.json() # print(_alerts) if len(_alerts) == 0: messages = [(u'Did not find anything.', u'info')] except Exception as e: print(e) messages = [(u'Failed to digest query.', u'danger')] return flask.Response( stream_template('template-search.html', user=user_id, logo=config['server']['logo'], form=flask.request.form, alerts=_alerts, messages=messages))