Skip to content

Commit 83f60d9

Browse files
authored
Merge pull request #185 from Will-Cooper/updates
Updates on the issue log
2 parents 0c9283a + 8051aa1 commit 83f60d9

File tree

6 files changed

+182
-59
lines changed

6 files changed

+182
-59
lines changed

requirements.txt

Lines changed: 87 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,87 @@
1-
astrodbkit>=2.2
2-
astropy>=5.2.0,<6
3-
bokeh==3.0.2
4-
flask>=3.0,<4
5-
flask-cors>=4.0,<5
6-
flask-wtf>=1.2,<2
7-
markdown2>=2.4,<3
8-
multiprocess>=0.70,<1
9-
numpy>=1.24,<2
10-
pandas>=2.0,<2.1
11-
pysqlite3>=0.5,<1
12-
pytest>=8.0,<9
13-
requests>=2.31,<3
14-
specutils>=1.12,<2
15-
sqlalchemy>=2.0,<3
16-
tqdm>=4.66,<5
17-
werkzeug>=3.0,<4
18-
wtforms>=3.1,<4
1+
antiorm==1.2.1
2+
asdf==4.1.0
3+
asdf-astropy==0.7.0
4+
asdf_coordinates_schemas==0.3.0
5+
asdf_standard==1.1.1
6+
asdf_transform_schemas==0.5.0
7+
asdf_wcs_schemas==0.4.0
8+
astrodbkit==2.2
9+
astropy==5.3.4
10+
astroquery==0.4.9.post1
11+
attrs==25.1.0
12+
backports.tarfile==1.2.0
13+
beautifulsoup4==4.13.3
14+
blinker==1.9.0
15+
bokeh==3.7.3
16+
certifi==2025.1.31
17+
cffi==1.17.1
18+
charset-normalizer==3.4.1
19+
click==8.1.8
20+
contourpy==1.3.1
21+
cryptography==44.0.0
22+
db==0.1.1
23+
db-sqlite3==0.0.1
24+
dill==0.3.9
25+
distlib==0.3.9
26+
distro==1.9.0
27+
filelock==3.16.1
28+
Flask==3.1.0
29+
Flask-Cors==4.0.2
30+
Flask-WTF==1.2.2
31+
greenlet==3.1.1
32+
gwcs==0.21.0
33+
html5lib==1.1
34+
idna==3.10
35+
importlib_metadata==8.6.1
36+
iniconfig==2.0.0
37+
iniparse==0.5
38+
itsdangerous==2.2.0
39+
jaraco.classes==3.4.0
40+
jaraco.context==6.0.1
41+
jaraco.functools==4.1.0
42+
jeepney==0.8.0
43+
Jinja2==3.1.5
44+
jmespath==1.0.1
45+
keyring==25.6.0
46+
markdown2==2.5.3
47+
MarkupSafe==3.0.2
48+
more-itertools==10.6.0
49+
multiprocess==0.70.17
50+
narwhals==1.41.0
51+
ndcube==2.3.0
52+
numpy==1.26.4
53+
packaging==24.2
54+
pandas==2.0.3
55+
pathlib2==2.3.7.post1
56+
pillow==11.1.0
57+
platformdirs==4.3.6
58+
pluggy==1.5.0
59+
pycparser==2.22
60+
pyerfa==2.0.1.5
61+
PyMySQL==1.1.1
62+
pyOpenSSL==24.3.0
63+
pysqlite3==0.5.4
64+
pytest==8.3.4
65+
python-dateutil==2.9.0.post0
66+
pytz==2024.2
67+
pyvo==1.6
68+
PyYAML==6.0.2
69+
requests==2.32.3
70+
scipy==1.15.1
71+
SecretStorage==3.3.3
72+
semantic-version==2.10.0
73+
six==1.17.0
74+
soupsieve==2.6
75+
specutils==1.19.0
76+
SQLAlchemy==2.0.38
77+
tornado==6.4.2
78+
tqdm==4.67.1
79+
typing_extensions==4.12.2
80+
tzdata==2025.1
81+
urllib3==2.3.0
82+
virtualenv==20.28.0
83+
webencodings==0.5.1
84+
Werkzeug==3.1.3
85+
WTForms==3.2.1
86+
xyzservices==2025.1.0
87+
zipp==3.21.0

simple_app/app_simple.py

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ def search():
4545
if (query := form.search.data) is None: # content in main searchbar
4646
query = ''
4747

48-
curdoc().template_variables['query'] = query # add query to bokeh curdoc
49-
curdoc().template_variables['ref_query'] = ref_query # add query to bokeh curdoc
48+
session['query'] = query # add query to bokeh curdoc
49+
session['ref_query'] = ref_query # add query to bokeh curdoc
5050
db = SimpleDB(db_file) # open database
5151

5252
# object search function
@@ -96,7 +96,7 @@ def coordinate_query():
9696
if (query := form.query.data) is None:
9797
query = ''
9898

99-
curdoc().template_variables['query'] = query
99+
session['query'] = query
100100
db = SimpleDB(db_file)
101101

102102
# parse query into ra, dec, radius
@@ -127,7 +127,7 @@ def full_text_search():
127127
query = ''
128128
limmaxrows = True
129129

130-
curdoc().template_variables['query'] = query
130+
session['query'] = query
131131
db = SimpleDB(db_file)
132132

133133
# search through the tables using the given query
@@ -160,14 +160,14 @@ def raw_query():
160160
if (query := form.sqlfield.data) is None:
161161
query = ''
162162

163-
curdoc().template_variables['query'] = query
163+
session['query'] = query
164164

165165
# attempt to query the database
166166
try:
167167
results: Optional[pd.DataFrame] = db.sql_query(query, fmt='pandas')
168168

169169
# catch any broken queries (should not activate as will be caught by validation)
170-
except (ResourceClosedError, OperationalError, IndexError, SqliteWarning, BadSQLError):
170+
except (ResourceClosedError, OperationalError, IndexError, SqliteWarning, BadSQLError, ProgrammingError):
171171
results = pd.DataFrame()
172172

173173
results = reference_handle(results, db_file, True)
@@ -188,7 +188,7 @@ def solo_result(query: str):
188188
query: str
189189
The query -- full match to a main ID
190190
"""
191-
curdoc().template_variables['query'] = query
191+
session['query'] = query
192192
db = SimpleDB(db_file)
193193

194194
# search database for given object
@@ -199,6 +199,7 @@ def solo_result(query: str):
199199
except KeyError:
200200
abort(404, f'"{query}" does match any result in SIMPLE!')
201201
return
202+
202203
everything = Inventory(resultdict, db_file)
203204

204205
# create camd and spectra plots
@@ -283,7 +284,7 @@ def create_file_for_download(key: str):
283284
key: str
284285
The dataframe string
285286
"""
286-
query = curdoc().template_variables['query']
287+
query: str = session.get('query')
287288
db = SimpleDB(db_file)
288289

289290
# search for a given object and a given key
@@ -305,7 +306,7 @@ def create_files_for_solo_download():
305306
"""
306307
Creates and downloads all dataframes from solo results
307308
"""
308-
query = curdoc().template_variables['query']
309+
query = session.get('query')
309310
db = SimpleDB(db_file)
310311

311312
# search for a given object
@@ -328,7 +329,7 @@ def create_spectra_files_for_download():
328329
"""
329330
Downloads the spectra files and zips together
330331
"""
331-
query = curdoc().template_variables['query']
332+
query = session.get('query')
332333
db = SimpleDB(db_file)
333334

334335
# search for a given object and specifically its spectra
@@ -346,13 +347,35 @@ def create_spectra_files_for_download():
346347
abort(400, 'Could not download fits')
347348

348349

350+
@app_simple.route('/write_multi_spectra', methods=['GET'])
351+
def create_multi_spectra_files_for_download():
352+
"""
353+
Downloads the spectra files and zips together
354+
"""
355+
query = session.get('query')
356+
db = SimpleDB(db_file)
357+
358+
# search for the spectra within a given free search
359+
resultdict: Dict[str, pd.DataFrame] = db.search_string(query, fmt='pandas', verbose=False)
360+
spectra_df: pd.DataFrame = resultdict['Spectra']
361+
362+
# write all spectra for object to zipped file
363+
zipped = write_spec_files(spectra_df.access_url.values)
364+
if zipped is not None:
365+
response = Response(zipped, mimetype='application/zip')
366+
response = control_response(response, app_type='zip')
367+
return response
368+
369+
abort(400, 'Could not download fits')
370+
371+
349372
@app_simple.route('/write_filt', methods=['GET'])
350373
def create_file_for_filtered_download():
351374
"""
352375
Creates and downloads the shown dataframe when in filtered search
353376
"""
354-
query = curdoc().template_variables['query']
355-
refquery = curdoc().template_variables['ref_query']
377+
query = session.get('query')
378+
refquery = session.get('ref_query')
356379
db = SimpleDB(db_file)
357380

358381
# search for a given object and a full text search at the same time
@@ -375,7 +398,7 @@ def create_file_for_coordinate_download():
375398
"""
376399
Creates and downloads the shown dataframe when in coordinate search
377400
"""
378-
query = curdoc().template_variables['query']
401+
query = session.get('query')
379402
db = SimpleDB(db_file)
380403

381404
# query the database for given coordinates and parse those coordinates
@@ -401,12 +424,12 @@ def create_file_for_full_download(key: str):
401424
key: str
402425
The dataframe string
403426
"""
404-
query = curdoc().template_variables['query']
427+
query = session.get('query')
405428
db = SimpleDB(db_file)
406429

407430
# search database with a free-text search and specific table
408431
resultdict: Dict[str, pd.DataFrame] = db.search_string(query, fmt='pandas', verbose=False)
409-
432+
print(query, key, resultdict.keys())
410433
# write to csv
411434
if key in resultdict:
412435
results: pd.DataFrame = resultdict[key]
@@ -422,7 +445,7 @@ def create_files_for_multi_download():
422445
"""
423446
Creates and downloads all dataframes from full results
424447
"""
425-
query = curdoc().template_variables['query']
448+
query = session.get('query')
426449
db = SimpleDB(db_file)
427450

428451
# search with full-text search
@@ -439,7 +462,7 @@ def create_file_for_sql_download():
439462
"""
440463
Creates and downloads the shown dataframe when in sql query
441464
"""
442-
query = curdoc().template_variables['query']
465+
query = session.get('query')
443466
db = SimpleDB(db_file)
444467

445468
# query database via sql

simple_app/plots.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -333,14 +333,14 @@ def sky_plot() -> figure:
333333
_p_sky = figure(title='Sky Plot', outer_height=500,
334334
active_scroll='wheel_zoom', active_drag='box_zoom',
335335
tools='pan,wheel_zoom,box_zoom,box_select,reset',
336-
sizing_mode='stretch_width', x_range=[-180, 180], y_range=[-90, 90])
336+
sizing_mode='stretch_width', x_range=Range1d(-180, 180), y_range=Range1d(-90, 90))
337337

338338
# background for skyplot
339339
_p_sky.ellipse(x=0, y=0, width=360, height=180, color='#444444', name='background')
340340

341341
# scatter plot for sky plot
342-
circle = _p_sky.circle(source=full_cds, x='ra_projected', y='dec_projected',
343-
size=6, name='circle', color='ghostwhite')
342+
circle = _p_sky.scatter(marker='circle', source=full_cds, x='ra_projected', y='dec_projected',
343+
size=6, name='circle', color='ghostwhite')
344344

345345
# bokeh tools for sky plot
346346
this_hover = HoverTool(renderers=[circle, ], tooltips=tooltips)
@@ -367,7 +367,8 @@ def colour_colour_plot() -> Tuple[figure, Toggle, Toggle, Select, Select]:
367367
_p_colour_colour = bokeh_formatter(_p_colour_colour)
368368

369369
# scatter plot for colour-colour
370-
full_plot = _p_colour_colour.circle(x=x_full_name, y=y_full_name, source=full_cds, size=6, color=cmap)
370+
full_plot = _p_colour_colour.scatter(marker='circle', x=x_full_name, y=y_full_name, source=full_cds, size=6,
371+
color=cmap)
371372

372373
# colour bar for colour-colour plot
373374
cbar = ColorBar(color_mapper=cmap['transform'], label_standoff=12,
@@ -395,6 +396,8 @@ def colour_colour_plot() -> Tuple[figure, Toggle, Toggle, Select, Select]:
395396
args={'full_plot': full_plot, 'full_data': full_cds.data,
396397
'y_button': _button_y_flip, 'y_axis': _p_colour_colour.yaxis[0],
397398
'y_range': _p_colour_colour.y_range}))
399+
_p_colour_colour.js_on_event('reset', CustomJS(args=dict(dropdown_x=_dropdown_x, dropdown_y=_dropdown_y),
400+
code=js_callbacks.reset_dropdown))
398401
return _p_colour_colour, _button_x_flip, _button_y_flip, _dropdown_x, _dropdown_y
399402

400403
def colour_absolute_magnitude_diagram() -> Tuple[figure, Toggle, Toggle, Select, Select]:
@@ -413,7 +416,8 @@ def colour_absolute_magnitude_diagram() -> Tuple[figure, Toggle, Toggle, Select,
413416
_p_camd = bokeh_formatter(_p_camd)
414417

415418
# scatter plot for camd
416-
full_mag_plot = _p_camd.circle(x=x_full_name, y=y_full_name, source=full_cds, size=6, color=cmap)
419+
full_mag_plot = _p_camd.scatter(marker='circle', x=x_full_name, y=y_full_name, source=full_cds, size=6,
420+
color=cmap)
417421

418422
# colour bar for camd
419423
cbar = ColorBar(color_mapper=cmap['transform'], label_standoff=12,
@@ -439,6 +443,8 @@ def colour_absolute_magnitude_diagram() -> Tuple[figure, Toggle, Toggle, Select,
439443
args={'full_plot': full_mag_plot,
440444
'full_data': full_cds.data, 'y_button': _button_mag_y_flip,
441445
'y_axis': _p_camd.yaxis[0], 'y_range': _p_camd.y_range}))
446+
_p_camd.js_on_event('reset', CustomJS(args=dict(dropdown_x=_dropdown_mag_x, dropdown_y=_dropdown_mag_y),
447+
code=js_callbacks.reset_dropdown))
442448
return _p_camd, _button_mag_x_flip, _button_mag_y_flip, _dropdown_mag_x, _dropdown_mag_y
443449

444450
# gather all necessary data including parallaxes, spectral types and bands
@@ -491,8 +497,8 @@ def colour_absolute_magnitude_diagram() -> Tuple[figure, Toggle, Toggle, Select,
491497
absmagnames = absmagnames[~np.isin(absmagnames, bad_cols)]
492498
absmag_shown_name = [name_simplifier(mag) for mag in absmagnames]
493499
dropdown_menu_mag = [*zip(absmagnames, absmag_shown_name)]
494-
y_full_name = absmagnames[0]
495-
y_shown_name = absmag_shown_name[0]
500+
y_full_name = absmagnames[1]
501+
y_shown_name = absmag_shown_name[1]
496502

497503
# camd plot
498504
p_camd, button_mag_x_flip, button_mag_y_flip, dropdown_mag_x, dropdown_mag_y = colour_absolute_magnitude_diagram()
@@ -650,13 +656,13 @@ def camd_plot(query: str, everything: Inventory, all_bands: np.ndarray, all_resu
650656

651657
# scatter plot for given object
652658
this_cds = ColumnDataSource(data=this_photometry)
653-
this_plot = p.square(x=x_full_name, y=y_full_name, source=this_cds,
654-
color=cmap, size=20) # plot for this object
659+
this_plot = p.scatter(marker='square', x=x_full_name, y=y_full_name, source=this_cds,
660+
color=cmap, size=20) # plot for this object
655661

656662
# scatter plot for all data
657663
cds_full = ColumnDataSource(data=all_results_full) # bokeh cds object
658-
full_plot = p.circle(x=x_full_name, y=y_full_name, source=cds_full,
659-
color=cmap, alpha=0.5, size=6) # plot all objects
664+
full_plot = p.scatter(marker='circle', x=x_full_name, y=y_full_name, source=cds_full,
665+
color=cmap, alpha=0.5, size=6) # plot all objects
660666
full_plot.level = 'underlay' # put full plot underneath this plot
661667

662668
# colour bar
@@ -683,6 +689,8 @@ def camd_plot(query: str, everything: Inventory, all_bands: np.ndarray, all_resu
683689
args={'full_plot': full_plot, 'this_plot': this_plot,
684690
'full_data': cds_full.data, 'y_button': button_y_flip,
685691
'y_axis': p.yaxis[0], 'y_range': p.y_range}))
692+
p.js_on_event('reset', CustomJS(args=dict(dropdown_x=dropdown_x, dropdown_y=dropdown_y),
693+
code=js_callbacks.reset_dropdown))
686694

687695
# creating bokeh layout and html
688696
plots = column(p, row(dropdown_x,
@@ -705,6 +713,6 @@ def main_plots():
705713

706714

707715
if __name__ == '__main__':
708-
ARGS, DB_FILE, PHOTOMETRIC_FILTERS, ALL_RESULTS, ALL_RESULTS_FULL, VERSION_STR,\
716+
ARGS, DB_FILE, PHOTOMETRIC_FILTERS, ALL_RESULTS, ALL_RESULTS_FULL, VERSION_STR, \
709717
ALL_PHOTO, ALL_BANDS, ALL_PLX, ALL_SPTS = main_utils()
710718
NIGHTSKYTHEME, JSCALLBACKS = main_plots()

simple_app/simple_callbacks.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,4 +289,15 @@ function reset_slider (spectra_slide) {
289289
spectra_slide.value = [0.81, 0.82];
290290
spectra_slide.change.emit();
291291

292+
}
293+
294+
function reset_dropdown(dropdown_x, dropdown_y) {
295+
296+
// resetting the dropdown columns when reset button pressed
297+
dropdown_x.value = dropdown_x.options[0][0];
298+
dropdown_y.value = dropdown_y.options[1][0];
299+
300+
dropdown_x.change.emit();
301+
dropdown_y.change.emit();
302+
292303
}

0 commit comments

Comments
 (0)