Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements for the search page #541

Merged
merged 50 commits into from
Jan 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
36a4e5e
Toggle the sidebar and quickview popup on client side, to avoid unnec…
karpov-sv Dec 13, 2023
4def755
New smart search bar, initial version.
karpov-sv Dec 15, 2023
193f05f
Option to limit the number of latest objects in class-based search
karpov-sv Dec 15, 2023
299c5ac
Show some basic info on what we were searching for
karpov-sv Dec 15, 2023
756aef0
Improve the layout of search results
karpov-sv Dec 15, 2023
3391f47
Quick fields implemented
karpov-sv Dec 17, 2023
ca960ed
Support for specifying time window for the cone search
karpov-sv Dec 18, 2023
165841a
Before/after time support for class-based search
karpov-sv Dec 18, 2023
199277b
Now the radius is in arcseconds everywhere, to make it consistent
karpov-sv Dec 18, 2023
ee8dee5
Fix the cone search size
karpov-sv Dec 18, 2023
fa91790
Hide the logo if screen width is smaller than 500px, or screen height…
karpov-sv Dec 19, 2023
eb0c1f8
Make the last commit slightly less restrictive of min width
karpov-sv Dec 19, 2023
60b8166
More responsive behaviour for quick fields
karpov-sv Dec 19, 2023
30a82f2
Make search bar properly round, again
karpov-sv Dec 19, 2023
1864199
Merge branch 'astrolabsoftware:master' into search
karpov-sv Dec 22, 2023
2ef7210
Support SSO queries
karpov-sv Dec 23, 2023
64effad
Merge branch 'astrolabsoftware:master' into search
karpov-sv Dec 24, 2023
278a415
Remove capitalization heuristics for SSO names that are not needed an…
karpov-sv Dec 24, 2023
0d379de
Minor adjustments for the search hints
karpov-sv Dec 24, 2023
a396000
Merge branch 'astrolabsoftware:master' into search
karpov-sv Dec 24, 2023
500b8e2
Fix edge case error in cutout zooming
karpov-sv Dec 25, 2023
875666f
Toggleable card-based display for search results
karpov-sv Dec 26, 2023
827cb3c
Summary page badges now include nearest objects information
karpov-sv Dec 26, 2023
5ae668c
Fix displaying explorer results in results card
karpov-sv Dec 26, 2023
0ed25af
Fix layout issues for card mode
karpov-sv Dec 26, 2023
bee52e2
Fix Aladin popup in card view
karpov-sv Dec 26, 2023
4814d20
Redisplay the index page on change of URL parameters, e.g. when click…
karpov-sv Dec 26, 2023
d2c3a43
Scroll to top on paginate, and add tiny badge with card number or ang…
karpov-sv Dec 26, 2023
71431e8
Remove carousel popup as it is now superseded with new card view
karpov-sv Dec 26, 2023
8a55146
Use the same error bar style for preview lightcurves
karpov-sv Dec 27, 2023
78c170f
More consistent look between table and card views
karpov-sv Dec 27, 2023
78a9b40
Slightly more case-insensitive parsing, and more query construction p…
karpov-sv Dec 27, 2023
7e0f00c
Ignore case when matching with autocomplete triggers. Also add button…
karpov-sv Dec 28, 2023
5d33e73
A bit more help
karpov-sv Dec 28, 2023
7daf22c
Disable input clear button when there is no input
karpov-sv Dec 28, 2023
02bb7d1
Search history - initial implementation, not so good aesthetically
karpov-sv Dec 29, 2023
99bc24e
Search history moved to an icon in main search bar
karpov-sv Dec 29, 2023
d505042
Fix history menu order (latest on top)
karpov-sv Dec 29, 2023
5d5412d
Improve the searchbar documentation, and add the badges for tracklet …
karpov-sv Dec 29, 2023
40af3ed
Make explorer API more consistent in handling date ranges. Also, add …
karpov-sv Dec 30, 2023
95f0baf
Date range search support in the search field
karpov-sv Dec 30, 2023
f410816
Fix triggering popup menu on sub-words
karpov-sv Dec 30, 2023
7a3582f
Reduce the precision of coordinates in card view
karpov-sv Dec 31, 2023
3b07395
Make preview lightcurve consistent with main one in showing negative …
karpov-sv Dec 31, 2023
1793b88
Anomaly search using 'Anomaly' class name
karpov-sv Jan 1, 2024
cd9f8f5
Random search added
karpov-sv Jan 1, 2024
8ad01ef
Only show latest alerts from random objects
karpov-sv Jan 2, 2024
f192b3d
Optionally use local API directly, to avoid exhaustion of the pool of…
karpov-sv Jan 4, 2024
f7aced7
Fix calling GET methods from the API
karpov-sv Jan 4, 2024
a259880
Fix indentation
karpov-sv Jan 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
args = yaml.load(open('config.yml'), yaml.Loader)

APIURL = args['APIURL']
LOCALAPI = args.get('LOCALAPI', False)

# bootstrap theme
external_stylesheets = [
Expand Down
53 changes: 28 additions & 25 deletions apps/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,28 +266,28 @@ def layout():
'description': 'Conesearch radius in arcsec. Maximum is 36,000 arcseconds (10 degrees).'
},
{
'name': 'startdate_conesearch',
'name': 'startdate',
'required': False,
'group': 1,
'description': '[Optional] Starting date in UTC for the conesearch query.'
'group': None,
'description': '[Optional] Starting date in UTC, as either ISO string, JD or MJD.'
},
{
'name': 'window_days_conesearch',
'name': 'stopdate',
'required': False,
'group': 1,
'description': '[Optional] Time window in days for the conesearch query.'
'group': None,
'description': '[Optional] Stopping date in UTC, as either ISO string, JD or MJD.'
},
{
'name': 'startdate',
'required': True,
'group': 2,
'description': 'Starting date in UTC'
'name': 'window',
'required': False,
'group': None,
'description': '[Optional] Time window in days, may be used instead of stopdate'
},
{
'name': 'window',
'required': True,
'group': 2,
'description': 'Time window in minutes. Maximum is 180 minutes.'
'name': 'n',
'required': False,
'group': None,
'description': 'Maximal number of alerts to return. Default is 1000.'
},
{
'name': 'output-format',
Expand Down Expand Up @@ -789,24 +789,27 @@ def query_db(payload=None):

# Check the user specifies only one group
all_groups = [i['group'] for i in args_explorer if i['group'] is not None and i['name'] in payload]
if len(np.unique(all_groups)) != 1:
if len(np.unique(all_groups)) > 1:
rep = {
'status': 'error',
'text': "You need to set parameters from the same group\n"
}
return Response(str(rep), 400)

# Check the user specifies all parameters within a group
user_group = np.unique(all_groups)[0]
required_args = [i['name'] for i in args_explorer if i['group'] == user_group]
required = [i['required'] for i in args_explorer if i['group'] == user_group]
for required_arg, required_ in zip(required_args, required):
if (required_arg not in payload) and required_:
rep = {
'status': 'error',
'text': "A value for `{}` is required for group {}. Use GET to check arguments.\n".format(required_arg, user_group)
}
return Response(str(rep), 400)
if len(np.unique(all_groups)) == 1:
user_group = np.unique(all_groups)[0]
required_args = [i['name'] for i in args_explorer if i['group'] == user_group]
required = [i['required'] for i in args_explorer if i['group'] == user_group]
for required_arg, required_ in zip(required_args, required):
if (required_arg not in payload) and required_:
rep = {
'status': 'error',
'text': "A value for `{}` is required for group {}. Use GET to check arguments.\n".format(required_arg, user_group)
}
return Response(str(rep), 400)
else:
user_group = None

pdfs = return_explorer_pdf(payload, user_group)

Expand Down
18 changes: 9 additions & 9 deletions apps/api/doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@
you should use the `Retrieve single object data` service instead.

Currently, you cannot query using several conditions.
You must choose among `Search by Object ID` (group 0), `Conesearch` (group 1), or `Search by Date` (group 2).
You must choose among `Search by Object ID` and `Conesearch` / `Search by Date`.
In a future release, you will be able to combine searches.
The list of arguments for querying the Fink alert database can be found at https://fink-portal.org/api/v1/explorer.

Expand Down Expand Up @@ -365,8 +365,8 @@
'ra': '193.822',
'dec': '2.89732',
'radius': '5',
'startdate_conesearch': '2021-06-25 05:59:37.000',
'window_days_conesearch': 7
'startdate': '2021-06-25 05:59:37.000',
'window': 7
}
)

Expand All @@ -386,8 +386,8 @@

### Search by Date

Choose a starting date and a time window to see all alerts in this period.
Dates are in UTC, and the time window in minutes.
Choose a starting date and stopping date or a time window to see all alerts in this period.
Dates are in UTC, and the time window in days (but should not exceed 3 hours).
Example of valid search:

* 2021-07-01 05:59:37.000
Expand All @@ -396,10 +396,10 @@

```bash
# Get all objects between 2021-07-01 05:59:37.000 and 2021-07-01 06:09:37.000 UTC
curl -H "Content-Type: application/json" -X POST -d '{"startdate":"2021-07-01 05:59:37.000", "window":"10"}' https://fink-portal.org/api/v1/explorer -o datesearch.json
curl -H "Content-Type: application/json" -X POST -d '{"startdate":"2021-07-01 05:59:37.000", "window":"0.007"}' https://fink-portal.org/api/v1/explorer -o datesearch.json

# you can also specify parameters in the URL, e.g. with wget:
wget "https://fink-portal.org/api/v1/explorer?startdate=2021-07-01 05:59:37.000&window=10&output-format=json" -O datesearch.json
wget "https://fink-portal.org/api/v1/explorer?startdate=2021-07-01 05:59:37.000&window=0.007&output-format=json" -O datesearch.json
```

In python, you would use
Expand All @@ -413,7 +413,7 @@
'https://fink-portal.org/api/v1/explorer',
json={
'startdate': '2021-07-01 05:59:37.000',
'window': '10'
'window': '0.007'
}
)

Expand Down Expand Up @@ -1795,4 +1795,4 @@
2 number 624188
3 ssnamenr 624188
```
"""
"""
71 changes: 34 additions & 37 deletions apps/api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
from apps.utils import format_hbase_output
from apps.utils import extract_cutouts
from apps.utils import hbase_type_converter
from apps.utils import isoify_time

from apps.euclid.utils import load_euclid_header
from apps.euclid.utils import add_columns
Expand Down Expand Up @@ -186,7 +187,24 @@ def return_explorer_pdf(payload: dict, user_group: int) -> pd.DataFrame:
out: pandas dataframe
"""
truncated = False

if 'startdate' in payload:
jd_start = Time(isoify_time(payload['startdate'])).jd
else:
jd_start = Time('2019-11-01 00:00:00').jd

if 'stopdate' in payload:
jd_stop = Time(isoify_time(payload['stopdate'])).jd
elif 'window' in payload and 'startdate' in payload:
window = float(payload['window'])
jd_stop = jd_start + window
else:
jd_stop = Time.now().jd

n = int(payload.get('n', 1000))

if user_group == 0:
# objectId search
client = connect_to_hbase_table('ztf')
results = {}
for oid in payload['objectId'].split(','):
Expand All @@ -201,21 +219,15 @@ def return_explorer_pdf(payload: dict, user_group: int) -> pd.DataFrame:
results.update(result)

schema_client = client.schema()
if user_group == 1:
elif user_group == 1:
# Conesearch with optional date range
client = connect_to_hbase_table('ztf.pixel128')
client.setLimit(n)

# Interpret user input
ra, dec = payload['ra'], payload['dec']
radius = payload['radius']

if 'startdate_conesearch' in payload:
startdate = payload['startdate_conesearch']
else:
startdate = None
if 'window_days_conesearch' in payload and payload['window_days_conesearch'] is not None:
window_days = float(payload['window_days_conesearch'])
else:
window_days = 1.0

if float(radius) > 18000.:
rep = {
'status': 'error',
Expand Down Expand Up @@ -254,24 +266,12 @@ def return_explorer_pdf(payload: dict, user_group: int) -> pd.DataFrame:
inclusive=True
)

# For the future: we could set client.setRangeScan(True)
# and pass directly the time boundaries here instead of
# grouping by later.

# Filter by time - logic to be improved...
if startdate is not None:
if ':' in str(startdate):
jdstart = Time(startdate).jd
elif str(startdate).startswith('24'):
jdstart = Time(startdate, format='jd').jd
else:
jdstart = Time(startdate, format='mjd').jd
jdend = jdstart + window_days

# Filter by time
if 'startdate' in payload:
client.setRangeScan(True)
results = {}
for pix in pixs:
to_search = "key:key:{}_{},key:key:{}_{}".format(pix, jdstart, pix, jdend)
to_search = "key:key:{}_{},key:key:{}_{}".format(pix, jd_start, pix, jd_stop)
result = client.scan(
"",
to_search,
Expand All @@ -281,7 +281,7 @@ def return_explorer_pdf(payload: dict, user_group: int) -> pd.DataFrame:
results.update(result)
client.setRangeScan(False)
else:
client = connect_to_hbase_table('ztf.pixel128')
# Do we really need this separate branch?.. Is it much faster than range scan?..
results = {}
for pix in pixs:
to_search = "key:key:{}".format(pix)
Expand All @@ -295,21 +295,18 @@ def return_explorer_pdf(payload: dict, user_group: int) -> pd.DataFrame:

schema_client = client.schema()
truncated = True
elif user_group == 2:
else:
# Plain date search
client = connect_to_hbase_table('ztf.jd')
if int(payload['window']) > 180:
rep = {
'status': 'error',
'text': "`window` cannot be bigger than 180 minutes.\n"
}
return Response(str(rep), 400)
# Time to jd
jd_start = Time(payload['startdate']).jd
jd_end = jd_start + TimeDelta(int(payload['window']) * 60, format='sec').jd

# Limit the time window to 3 hours days
if jd_stop - jd_start > 3/24:
jd_stop = jd_start + 3/24

# Send the request. RangeScan.
client.setRangeScan(True)
to_evaluate = "key:key:{},key:key:{}".format(jd_start, jd_end)
client.setLimit(n)
to_evaluate = "key:key:{},key:key:{}".format(jd_start, jd_stop)
results = client.scan(
"",
to_evaluate,
Expand Down
Loading
Loading