AstroToolkit 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
AstroToolkit/Tools.py ADDED
@@ -0,0 +1,1222 @@
1
+ from bokeh.plotting import figure, output_file
2
+ from bokeh.layouts import gridplot, row, column
3
+ from bokeh.models import CustomJS, Button
4
+ from bokeh import events
5
+ from bokeh.layouts import layout
6
+ import pandas as pd
7
+
8
+ '''
9
+ Changelog:
10
+ - Re-wrote everything in Bokeh
11
+ - Cleaned up imports
12
+
13
+ Known Issues:
14
+ - Detections at large distance from focus are slightly innacurate due to lack of projection support in Bokeh
15
+
16
+ To Do:
17
+ - Clean up errors
18
+ - Sort structure https://docs.python.org/3/reference/import.html#package-relative-imports
19
+ '''
20
+
21
+ # Data Queries ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
22
+
23
+ def panstarrsquery(source=None,pos=None,radius=3):
24
+ from .Surveys.PanSTARRS import PanSTARRSQueryCoords
25
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
26
+
27
+ if source!=None and pos!=None:
28
+ raise Exception('simulatenous source and pos input detected')
29
+
30
+ if source!=None:
31
+ gaia_data=gaiaquery(source=source)
32
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
33
+
34
+ pos_corrected=CorrectPM([2016,0],[2012,0],ra,dec,pmra,pmdec)
35
+ ra,dec=pos_corrected[0],pos_corrected[1]
36
+ elif pos!=None:
37
+ ra,dec=pos[0],pos[1]
38
+ else:
39
+ raise Exception('either source or pos input required')
40
+ return None
41
+
42
+ data=PanSTARRSQueryCoords(ra,dec,radius)
43
+ return data
44
+
45
+ def skymapperquery(source=None,pos=None,radius=3):
46
+ from .Surveys.SkyMapper import SkyMapperQueryCoords
47
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
48
+
49
+ if source!=None and pos!=None:
50
+ raise Exception('simulatenous source and pos input detected')
51
+
52
+ if source!=None:
53
+ gaia_data=gaiaquery(source=source)
54
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
55
+
56
+ pos_corrected=CorrectPM([2016,0],[2016,0],ra,dec,pmra,pmdec)
57
+ ra,dec=pos_corrected[0],pos_corrected[1]
58
+ elif pos!=None:
59
+ ra,dec=pos[0],pos[1]
60
+ else:
61
+ raise Exception('either source or pos input required')
62
+ return None
63
+
64
+ data=SkyMapperQueryCoords(ra,dec,radius)
65
+ return data
66
+
67
+ def gaiaquery(source=None,pos=None,radius=3,catalogue='dr3'):
68
+ from .Surveys.Gaia import GaiaQueryDesignation
69
+ from .Surveys.Gaia import GaiaQueryCoords
70
+
71
+ if source!=None and pos!=None:
72
+ raise Exception('simulatenous source and pos input detected')
73
+
74
+ if source!=None:
75
+ data=GaiaQueryDesignation(Designation=source)
76
+ elif pos!=None:
77
+ ra,dec=pos[0],pos[1]
78
+ data=GaiaQueryCoords(ra,dec)
79
+ else:
80
+ raise Exception('either source or pos input required')
81
+
82
+ return data
83
+
84
+ def galexquery(source=None,pos=None,radius=3):
85
+ from .Surveys.GALEX import GALEXQueryCoords
86
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
87
+
88
+ if source!=None and pos!=None:
89
+ raise Exception('simulatenous source and pos input detected')
90
+
91
+ if source!=None:
92
+ gaia_data=gaiaquery(source=source)
93
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
94
+
95
+ pos_corrected=CorrectPM([2016,0],[2007,0],ra,dec,pmra,pmdec)
96
+ ra,dec=pos_corrected[0],pos_corrected[1]
97
+ elif pos!=None:
98
+ ra,dec=pos[0],pos[1]
99
+ else:
100
+ raise Exception('either source or pos input required')
101
+ return None
102
+
103
+ data=GALEXQueryCoords(ra,dec,radius)
104
+ return data
105
+
106
+ def rosatquery(source=None,pos=None,radius=3):
107
+ from .Surveys.ROSAT import ROSATQueryCoords
108
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
109
+
110
+ if source!=None and pos!=None:
111
+ raise Exception('simulatenous source and pos input detected')
112
+
113
+ if source!=None:
114
+ gaia_data=gaiaquery(source=source)
115
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
116
+
117
+ pos_corrected=CorrectPM([2016,0],[1991,0],ra,dec,pmra,pmdec)
118
+ ra,dec=pos_corrected[0],pos_corrected[1]
119
+ elif pos!=None:
120
+ ra,dec=pos[0],pos[1]
121
+ else:
122
+ raise Exception('either source or pos input required')
123
+ return None
124
+
125
+ data=ROSATQueryCoords(ra,dec,radius)
126
+ return data
127
+
128
+ def sdssquery(source=None,pos=None,radius=3):
129
+ from .Surveys.SDSS import get_data
130
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
131
+
132
+ if source!=None and pos!=None:
133
+ raise Exception('simulatenous source and pos input detected')
134
+
135
+ if source!=None:
136
+ gaia_data=gaiaquery(source=source)
137
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
138
+
139
+ pos_corrected=CorrectPM([2016,0],[2017,0],ra,dec,pmra,pmdec)
140
+ ra,dec=pos_corrected[0],pos_corrected[1]
141
+ elif pos!=None:
142
+ ra,dec=pos[0],pos[1]
143
+ else:
144
+ raise Exception('either source or pos input required')
145
+ return None
146
+
147
+ data=get_data(ra=ra,dec=dec,radius=radius)
148
+ return data
149
+
150
+ def wisequery(source=None,pos=None,radius=3):
151
+ from .Surveys.WISE import get_data
152
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
153
+
154
+ if source!=None and pos!=None:
155
+ raise Exception('simulatenous source and pos input detected')
156
+
157
+ if source!=None:
158
+ gaia_data=gaiaquery(source=source)
159
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
160
+
161
+ pos_corrected=CorrectPM([2016,0],[2010,5],ra,dec,pmra,pmdec)
162
+ ra,dec=pos_corrected[0],pos_corrected[1]
163
+ elif pos!=None:
164
+ ra,dec=pos[0],pos[1]
165
+ else:
166
+ raise Exception('either source or pos input required')
167
+ return None
168
+
169
+ data=get_data(ra=ra,dec=dec,radius=radius)
170
+ return data
171
+
172
+ def twomassquery(source=None,pos=None,radius=3):
173
+ from .Surveys.TWOMASS import get_data
174
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
175
+
176
+ if source!=None and pos!=None:
177
+ raise Exception('simulatenous source and pos input detected')
178
+
179
+ if source!=None:
180
+ gaia_data=gaiaquery(source=source)
181
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
182
+
183
+ pos_corrected=CorrectPM([2016,0],[2010,5],ra,dec,pmra,pmdec)
184
+ ra,dec=pos_corrected[0],pos_corrected[1]
185
+ elif pos!=None:
186
+ ra,dec=pos[0],pos[1]
187
+ else:
188
+ raise Exception('either source or pos input required')
189
+ return None
190
+
191
+ data=get_data(ra=ra,dec=dec,radius=radius)
192
+ return data
193
+
194
+ # Imaging Queries ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
195
+
196
+ def getpanstarrsimage(source=None,pos=None,image_size=30,band='g',overlay=['gaia'],get_time=False):
197
+ from astropy.time import Time
198
+
199
+ from .Surveys.PanSTARRS import get_info
200
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
201
+ from .Surveys.PanSTARRS import get_plot
202
+ from .Overlays.Overlay_Selection import overlaySelection
203
+
204
+ if source!=None and pos!=None:
205
+ raise Exception('simulatenous source and pos input detected')
206
+
207
+ if source!=None:
208
+ # Fetch coordinates and proper motion for object
209
+ gaia_data=gaiaquery(source=source)
210
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
211
+
212
+ # Get an image and get the time it was taken
213
+ mjd=get_info(ra=ra,dec=dec,size=image_size,band=band)[1]
214
+ if mjd==None:
215
+ if get_time==False:
216
+ return None
217
+ else:
218
+ return None, None
219
+ imageTime=Time(mjd,format='mjd').to_datetime()
220
+ imageTime=[imageTime.year,imageTime.month]
221
+
222
+ # Correct for proper motion to this image time
223
+ pos_corrected=CorrectPM([2016,0],imageTime,ra,dec,pmra,pmdec)
224
+ ra,dec=pos_corrected[0],pos_corrected[1]
225
+
226
+ elif pos!=None:
227
+ # No proper motion correction
228
+ ra,dec=pos[0],pos[1]
229
+ mjd=get_info(ra=ra,dec=dec,size=image_size,band=band)[1]
230
+
231
+ if mjd==None:
232
+ if get_time==False:
233
+ return None
234
+ else:
235
+ return None, None
236
+ else:
237
+ raise Exception('either source or pos input required')
238
+
239
+ # Fetch final image using coordinates corrected to the time of the original image
240
+ plot=get_plot(ra=ra,dec=dec,size=image_size,band=band)
241
+
242
+ if plot==None:
243
+ if get_time==False:
244
+ return None
245
+ else:
246
+ return None, None
247
+
248
+ # Get half image size (in deg, used for detection size scaling)
249
+ border=image_size/7200
250
+
251
+ if source!=None:
252
+ plot,detections_made=overlaySelection(plot,ra,dec,overlay,mjd,image_size,border,pmra,pmdec)
253
+ elif pos!=None:
254
+ plot,detections_made=overlaySelection(plot,ra,dec,overlay,mjd,image_size,border)
255
+
256
+ if plot!=None and detections_made!=False:
257
+ plot.legend.click_policy="hide"
258
+
259
+ # Double click to hide legend
260
+ toggle_legend_js = CustomJS(args=dict(leg=plot.legend[0]), code='''
261
+ if (leg.visible) {
262
+ leg.visible = false
263
+ }
264
+ else {
265
+ leg.visible = true
266
+ }
267
+ ''')
268
+
269
+ plot.js_on_event(events.DoubleTap, toggle_legend_js)
270
+
271
+ if source!=None:
272
+ output_file(f'{source}_image.html')
273
+
274
+ elif pos!=None:
275
+ if pos[1]>=0:
276
+ output_file(f"{pos[0]}+{pos[1]}_image.html")
277
+ else:
278
+ output_file(f"{pos[0]}{pos[1]}_image.html")
279
+
280
+ if get_time==True:
281
+ imageTime=Time(mjd,format='mjd').to_datetime()
282
+ imageTime=[imageTime.year,imageTime.month]
283
+ return plot, imageTime
284
+ else:
285
+ return plot
286
+
287
+ def getskymapperimage(source=None,pos=None,image_size=30,band='g',overlay=['gaia'],get_time=False):
288
+ from astropy.time import Time
289
+
290
+ from .Surveys.SkyMapper import get_info
291
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
292
+ from .Surveys.SkyMapper import get_plot
293
+ from .Overlays.Overlay_Selection import overlaySelection
294
+
295
+ if source!=None and pos!=None:
296
+ raise Exception('simulatenous source and pos input detected')
297
+
298
+ if source!=None:
299
+ # Fetch coordinates and proper motion for object
300
+ gaia_data=gaiaquery(source=source)
301
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
302
+
303
+ # Get an image and get the time it was taken
304
+ mjd=get_info(ra=ra,dec=dec,size=image_size,band=band)[1]
305
+ if mjd==None:
306
+ if get_time==False:
307
+ return None
308
+ else:
309
+ return None, None
310
+ imageTime=Time(mjd,format='mjd').to_datetime()
311
+ imageTime=[imageTime.year,imageTime.month]
312
+
313
+ # Correct for proper motion to this image time
314
+ pos_corrected=CorrectPM([2016,0],imageTime,ra,dec,pmra,pmdec)
315
+ ra,dec=pos_corrected[0],pos_corrected[1]
316
+
317
+ elif pos!=None:
318
+ # No proper motion correction
319
+ ra,dec=pos[0],pos[1]
320
+ mjd=get_info(ra=ra,dec=dec,size=image_size,band=band)[1]
321
+
322
+ if mjd==None:
323
+ if get_time==False:
324
+ return None
325
+ else:
326
+ return None, None
327
+ else:
328
+ raise Exception('either source or pos input required')
329
+
330
+ # Fetch final image using coordinates corrected to the time of the original image
331
+ plot=get_plot(ra=ra,dec=dec,size=image_size,band=band)
332
+
333
+ if plot==None:
334
+ if get_time==False:
335
+ return None
336
+ else:
337
+ return None, None
338
+
339
+ # Get half image size (in deg, used for detection size scaling)
340
+ border=image_size/7200
341
+
342
+ if source!=None:
343
+ plot,detections_made=overlaySelection(plot,ra,dec,overlay,mjd,image_size,border,pmra,pmdec)
344
+ elif pos!=None:
345
+ plot,detections_made=overlaySelection(plot,ra,dec,overlay,mjd,image_size,border)
346
+
347
+ if plot!=None and detections_made!=False:
348
+ plot.legend.click_policy="hide"
349
+
350
+ # Double click to hide legend
351
+ toggle_legend_js = CustomJS(args=dict(leg=plot.legend[0]), code='''
352
+ if (leg.visible) {
353
+ leg.visible = false
354
+ }
355
+ else {
356
+ leg.visible = true
357
+ }
358
+ ''')
359
+
360
+ plot.js_on_event(events.DoubleTap, toggle_legend_js)
361
+
362
+ if source!=None:
363
+ output_file(f'{source}_image.html')
364
+
365
+ elif pos!=None:
366
+ if pos[1]>=0:
367
+ output_file(f"{pos[0]}+{pos[1]}_image.html")
368
+ else:
369
+ output_file(f"{pos[0]}{pos[1]}_image.html")
370
+
371
+ if get_time==True:
372
+ imageTime=Time(mjd,format='mjd').to_datetime()
373
+ imageTime=[imageTime.year,imageTime.month]
374
+ return plot, imageTime
375
+ else:
376
+ return plot
377
+
378
+ def getdssimage(source=None,pos=None,image_size=30,overlay=['gaia'],get_time=False):
379
+ from astropy.time import Time
380
+
381
+ from .Surveys.DSS import get_info
382
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
383
+ from .Surveys.DSS import get_plot
384
+ from .Overlays.Overlay_Selection import overlaySelection
385
+
386
+ if source!=None and pos!=None:
387
+ raise Exception('simulatenous source and pos input detected')
388
+
389
+ if source!=None:
390
+ # Fetch coordinates and proper motion for object
391
+ gaia_data=gaiaquery(source=source)
392
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
393
+
394
+ # Get an image and get the time it was taken
395
+ mjd=get_info(ra=ra,dec=dec,size=image_size)[1]
396
+ if mjd==None:
397
+ if get_time==False:
398
+ return None
399
+ else:
400
+ return None, None
401
+
402
+ imageTime=Time(mjd,format='mjd').to_datetime()
403
+ imageTime=[imageTime.year,imageTime.month]
404
+
405
+ # Correct for proper motion to this image time
406
+ pos_corrected=CorrectPM([2016,0],imageTime,ra,dec,pmra,pmdec)
407
+ ra,dec=pos_corrected[0],pos_corrected[1]
408
+
409
+ elif pos!=None:
410
+ # No proper motion correction
411
+ ra,dec=pos[0],pos[1]
412
+ mjd=get_info(ra=ra,dec=dec,size=image_size)[1]
413
+
414
+ if mjd==None:
415
+ if get_time==False:
416
+ return None
417
+ else:
418
+ return None, None
419
+ else:
420
+ raise Exception('either source or pos input required')
421
+
422
+ # Fetch final image using coordinates corrected to the time of the original image
423
+ plot=get_plot(ra=ra,dec=dec,size=image_size)
424
+
425
+ if plot==None:
426
+ if get_time==False:
427
+ return None
428
+ else:
429
+ return None, None
430
+
431
+ # Get half image size (in deg, used for detection size scaling)
432
+ border=image_size/7200
433
+
434
+ if source!=None:
435
+ plot,detections_made=overlaySelection(plot,ra,dec,overlay,mjd,image_size,border,pmra,pmdec)
436
+ elif pos!=None:
437
+ plot,detections_made=overlaySelection(plot,ra,dec,overlay,mjd,image_size,border)
438
+
439
+ plot.legend.click_policy="hide"
440
+
441
+ if plot!=None and detections_made!=None:
442
+ # Double click to hide legend
443
+ toggle_legend_js = CustomJS(args=dict(leg=plot.legend[0]), code='''
444
+ if (leg.visible) {
445
+ leg.visible = false
446
+ }
447
+ else {
448
+ leg.visible = true
449
+ }
450
+ ''')
451
+
452
+ plot.js_on_event(events.DoubleTap, toggle_legend_js)
453
+
454
+ if source!=None:
455
+ output_file(f'{source}_image.html')
456
+
457
+ elif pos!=None:
458
+ if pos[1]>=0:
459
+ output_file(f"{pos[0]}+{pos[1]}_image.html")
460
+ else:
461
+ output_file(f"{pos[0]}{pos[1]}_image.html")
462
+
463
+ if get_time==True:
464
+ imageTime=Time(mjd,format='mjd').to_datetime()
465
+ imageTime=[imageTime.year,imageTime.month]
466
+ return plot, imageTime
467
+ else:
468
+ return plot
469
+
470
+ # Photometry Queries ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
471
+
472
+ def getpanstarrsphot(radius=3,source=None,pos=None):
473
+ from .Surveys.PanSTARRS import PanSTARRSGetPhotometryCoords
474
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
475
+
476
+ if source!=None and pos!=None:
477
+ raise Exception('simulatenous source and pos input detected')
478
+
479
+ if source!=None:
480
+ gaia_data=gaiaquery(source=source)
481
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
482
+
483
+ pos_corrected=CorrectPM([2016,0],[2012,0],ra,dec,pmra,pmdec)
484
+ ra,dec=pos_corrected[0],pos_corrected[1]
485
+ elif pos!=None:
486
+ ra,dec=pos[0],pos[1]
487
+ else:
488
+ raise Exception('either source or pos input required')
489
+ return None
490
+
491
+ data=PanSTARRSGetPhotometryCoords(ra,dec,radius)
492
+ return data
493
+
494
+ def getskymapperphot(radius=3,source=None,pos=None):
495
+ from .Surveys.SkyMapper import SkyMapperGetPhotometryCoords
496
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
497
+
498
+ if source!=None and pos!=None:
499
+ raise Exception('simulatenous source and pos input detected')
500
+
501
+ if source!=None:
502
+ gaia_data=gaiaquery(source=source)
503
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
504
+
505
+ pos_corrected=CorrectPM([2016,0],[2016,0],ra,dec,pmra,pmdec)
506
+ ra,dec=pos_corrected[0],pos_corrected[1]
507
+ elif pos!=None:
508
+ ra,dec=pos[0],pos[1]
509
+ else:
510
+ raise Exception('either source or pos input required')
511
+ return None
512
+
513
+ data=SkyMapperGetPhotometryCoords(ra,dec,radius)
514
+ return data
515
+
516
+ def getgaiaphot(radius=3,source=None,pos=None):
517
+ from .Surveys.Gaia import GaiaGetPhotometryCoords
518
+ from .Surveys.Gaia import GaiaGetPhotometryDesignation
519
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
520
+
521
+ if source!=None and pos!=None:
522
+ raise Exception('simulatenous source and pos input detected')
523
+
524
+ if source!=None:
525
+ data=GaiaGetPhotometryDesignation(Designation=source)
526
+ elif pos!=None:
527
+ ra,dec=pos[0],pos[1]
528
+ data=GaiaGetPhotometryCoords(ra,dec,radius)
529
+ else:
530
+ raise Exception('either source or pos input required')
531
+ return None
532
+
533
+ return data
534
+
535
+ def getgalexphot(radius=3,source=None,pos=None):
536
+ from .Surveys.GALEX import GALEXGetPhotometryCoords
537
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
538
+
539
+ if source!=None and pos!=None:
540
+ raise Exception('simulatenous source and pos input detected')
541
+
542
+ if source!=None:
543
+ gaia_data=gaiaquery(source=source)
544
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
545
+
546
+ pos_corrected=CorrectPM([2016,0],[2007,0],ra,dec,pmra,pmdec)
547
+ ra,dec=pos_corrected[0],pos_corrected[1]
548
+ elif pos!=None:
549
+ ra,dec=pos[0],pos[1]
550
+ else:
551
+ raise Exception('either source or pos input required')
552
+ return None
553
+
554
+ data=GALEXGetPhotometryCoords(ra,dec,radius)
555
+
556
+ return data
557
+
558
+ def getsdssphot(radius=3,source=None,pos=None):
559
+ from .Surveys.SDSS import get_photometry
560
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
561
+
562
+ if source!=None and pos!=None:
563
+ raise Exception('simulatenous source and pos input detected')
564
+
565
+ if source!=None:
566
+ gaia_data=gaiaquery(source=source)
567
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
568
+
569
+ pos_corrected=CorrectPM([2016,0],[2007,0],ra,dec,pmra,pmdec)
570
+ ra,dec=pos_corrected[0],pos_corrected[1]
571
+ elif pos!=None:
572
+ ra,dec=pos[0],pos[1]
573
+ else:
574
+ raise Exception('either source or pos input required')
575
+ return None
576
+
577
+ data=get_photometry(ra=ra,dec=dec,radius=radius)
578
+ return data
579
+
580
+ def getwisephot(radius=3,source=None,pos=None):
581
+ from .Surveys.WISE import get_photometry
582
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
583
+
584
+ if source!=None and pos!=None:
585
+ raise Exception('simulatenous source and pos input detected')
586
+
587
+ if source!=None:
588
+ gaia_data=gaiaquery(source=source)
589
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
590
+
591
+ pos_corrected=CorrectPM([2016,0],[2007,0],ra,dec,pmra,pmdec)
592
+ ra,dec=pos_corrected[0],pos_corrected[1]
593
+ elif pos!=None:
594
+ ra,dec=pos[0],pos[1]
595
+ else:
596
+ raise Exception('either source or pos input required')
597
+ return None
598
+
599
+ data=get_photometry(ra=ra,dec=dec,radius=radius)
600
+ return data
601
+
602
+ def gettwomassphot(radius=3,source=None,pos=None):
603
+ from .Surveys.TWOMASS import get_photometry
604
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
605
+
606
+ if source!=None and pos!=None:
607
+ raise Exception('simulatenous source and pos input detected')
608
+
609
+ if source!=None:
610
+ gaia_data=gaiaquery(source=source)
611
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
612
+
613
+ pos_corrected=CorrectPM([2016,0],[2007,0],ra,dec,pmra,pmdec)
614
+ ra,dec=pos_corrected[0],pos_corrected[1]
615
+ elif pos!=None:
616
+ ra,dec=pos[0],pos[1]
617
+ else:
618
+ raise Exception('either source or pos input required')
619
+ return None
620
+
621
+ data=get_photometry(ra=ra,dec=dec,radius=radius)
622
+ return data
623
+
624
+ # Bulk Photometry Query
625
+
626
+ def getbulkphot(radius=3,source=None,pos=None):
627
+ from .Surveys.Gaia import GaiaGetPhotometryCoords
628
+ from .Surveys.GALEX import GALEXGetPhotometryCoords
629
+ from .Surveys.ROSAT import ROSATGetPhotometryCoords
630
+ from .Surveys.PanSTARRS import PanSTARRSGetPhotometryCoords
631
+ from .Surveys.SkyMapper import SkyMapperGetPhotometryCoords
632
+ from .Surveys.SDSS import get_photometry as get_phot_sdss
633
+ from .Surveys.WISE import get_photometry as get_phot_wise
634
+ from .Surveys.TWOMASS import get_photometry as get_phot_twomass
635
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
636
+
637
+ if source!=None and pos!=None:
638
+ raise Exception('simulatenous source and pos input detected')
639
+
640
+ if source!=None:
641
+ gaia_data=gaiaquery(source=source)
642
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
643
+
644
+ pos_corrected=CorrectPM([2016,0],[2012,0],ra,dec,pmra,pmdec)
645
+ ra_panstarrs,dec_panstarrs=pos_corrected[0],pos_corrected[1]
646
+
647
+ pos_corrected=CorrectPM([2016,0],[2016,0],ra,dec,pmra,pmdec)
648
+ ra_skymapper,dec_skymapper=pos_corrected[0],pos_corrected[1]
649
+
650
+ ra_gaia,dec_gaia=ra,dec
651
+
652
+ pos_corrected=CorrectPM([2016,0],[2007,0],ra,dec,pmra,pmdec)
653
+ ra_galex,dec_galex=pos_corrected[0],pos_corrected[1]
654
+
655
+ pos_corrected=CorrectPM([2016,0],[1991,0],ra,dec,pmra,pmdec)
656
+ ra_rosat,dec_rosat=pos_corrected[0],pos_corrected[1]
657
+
658
+ pos_corrected=CorrectPM([2016,0],[2017,0],ra,dec,pmra,pmdec)
659
+ ra_sdss,dec_sdss=pos_corrected[0],pos_corrected[1]
660
+
661
+ pos_corrected=CorrectPM([2016,0],[2010,5],ra,dec,pmra,pmdec)
662
+ ra_wise,dec_wise=pos_corrected[0],pos_corrected[1]
663
+
664
+ pos_corrected=CorrectPM([2016,0],[1999,0],ra,dec,pmra,pmdec)
665
+ ra_twomass,dec_twomass=pos_corrected[0],pos_corrected[1]
666
+
667
+ elif pos!=None:
668
+ ra_panstarrs,dec_panstarrs=pos[0],pos[1]
669
+ ra_skymapper,dec_skymapper=pos[0],pos[1]
670
+ ra_gaia,dec_gaia=pos[0],pos[1]
671
+ ra_galex,dec_galex=pos[0],pos[1]
672
+ ra_rosat,dec_rosat=pos[0],pos[1]
673
+ ra_sdss,dec_sdss=pos[0],pos[1]
674
+ ra_wise,dec_wise=pos[0],pos[1]
675
+ ra_twomass,dec_twomass=pos[0],pos[1]
676
+
677
+ else:
678
+ raise Exception('either source or pos input required')
679
+ return None
680
+
681
+ photometry={'gaia':None,'galex':None,'rosat':None,'panstarrs':None,'skymapper':None,'sdss':None,'wise':None,'twomass':None}
682
+
683
+ try:
684
+ data=GaiaGetPhotometryCoords(ra_gaia,dec_gaia,radius)
685
+ photometry['gaia']=data
686
+ except:
687
+ print('[Photometry: GetPhotometryCoords] Note: No Gaia photometry found using given coordinates and search radius')
688
+ try:
689
+ data=GALEXGetPhotometryCoords(ra_galex,dec_galex,radius)
690
+ photometry['galex']=data
691
+ except:
692
+ print('[Photometry: GetPhotometryCoords] Note: No GALEX photometry found using given coordinates and search radius')
693
+ try:
694
+ data=ROSATGetPhotometryCoords(ra_rosat,dec_rosat,radius)
695
+ photometry['rosat']=data
696
+ except:
697
+ print('[Photometry: GetPhotometryCoords] Note: No ROSAT photometry found using given coordinates and search radius')
698
+ try:
699
+ data=PanSTARRSGetPhotometryCoords(ra_panstarrs,dec_panstarrs,radius)
700
+ photometry['panstarrs']=data
701
+ except:
702
+ print('[Photometry: GetPhotometryCoords] Note: No Pan-STARRS photometry found using given coordinates and search radius')
703
+ try:
704
+ data=SkyMapperGetPhotometryCoords(ra_skymapper,dec_skymapper,radius)
705
+ photometry['skymapper']=data
706
+ except:
707
+ print('[Photometry: GetPhotometryCoords] Note: No SkyMapper photometry found using given coordinates and search radius')
708
+ try:
709
+ data=get_phot_sdss(ra=ra_sdss,dec=dec_sdss,radius=radius)
710
+ photometry['sdss']=data
711
+ except:
712
+ print('[Photometry: GetPhotometryCoords] Note: No SDSS photometry found using given coordinates and search radius')
713
+ try:
714
+ data=get_phot_wise(ra=ra_wise,dec=dec_wise,radius=radius)
715
+ photometry['wise']=data
716
+ except:
717
+ print('[Photometry: GetPhotometryCoords] Note: No WISE photometry found using given coordinates and search radius')
718
+ try:
719
+ data=get_phot_twomass(ra=ra_twomass,dec=dec_twomass,radius=radius)
720
+ photometry['twomass']=data
721
+ except:
722
+ print('[Photometry: GetPhotometryCoords] Note: No 2MASS photometry found using given coordinates and search radius')
723
+
724
+ return photometry
725
+
726
+ # Timeseries Queries -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
727
+
728
+ def ztfquery(source=None,pos=None,radius=3):
729
+ from .Surveys.ZTF import getData as getZTFData
730
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
731
+
732
+ if source!=None and pos!=None:
733
+ raise Exception('simulatenous source and pos input detected')
734
+
735
+ if source!=None:
736
+ gaia_data=gaiaquery(source=source)
737
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
738
+
739
+ pos_corrected=CorrectPM([2016,0],[2019,0],ra,dec,pmra,pmdec)
740
+ ra,dec=pos_corrected[0],pos_corrected[1]
741
+ elif pos!=None:
742
+ ra,dec=pos[0],pos[1]
743
+ else:
744
+ raise Exception('either source or pos input required')
745
+ return None
746
+
747
+ data=getZTFData(ra,dec,radius)
748
+ return data
749
+
750
+ # Timeseries Plotting ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
751
+
752
+ def getztflc(source=None,pos=None,radius=3,return_raw=False):
753
+ from .Surveys.ZTF import getLightCurve as getZTFLightCurve
754
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
755
+
756
+ if source!=None and pos!=None:
757
+ raise Exception('simulatenous source and pos input detected')
758
+
759
+ if source!=None:
760
+ gaia_data=gaiaquery(source=source)
761
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
762
+
763
+ pos_corrected=CorrectPM([2016,0],[2019,0],ra,dec,pmra,pmdec)
764
+ ra,dec=pos_corrected[0],pos_corrected[1]
765
+ elif pos!=None:
766
+ ra,dec=pos[0],pos[1]
767
+ else:
768
+ raise Exception('either source or pos input required')
769
+ return None
770
+
771
+ plot=getZTFLightCurve(ra,dec,radius,return_raw)
772
+
773
+ if source!=None:
774
+ output_file(f'{source}_lightcurve.html')
775
+
776
+ elif pos!=None:
777
+ if pos[1]>=0:
778
+ output_file(f"{pos[0]}+{pos[1]}_lightcurve.html")
779
+ else:
780
+ output_file(f"{pos[0]}{pos[1]}_lightcurve.html")
781
+
782
+ return plot
783
+
784
+ # SED Plotting -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
785
+
786
+ def getsed(source=None,pos=None,radius=3):
787
+ from .Figures.SED import get_plot
788
+
789
+ if source!=None and pos!=None:
790
+ raise Exception('simulatenous source and pos input detected')
791
+
792
+ if source!=None:
793
+ plot=get_plot(source=source,radius=radius)
794
+ elif pos!=None:
795
+ plot=get_plot(pos=pos,radius=radius)
796
+ else:
797
+ raise Exception('either source or pos input required')
798
+
799
+ if plot!=None:
800
+ plot.legend.click_policy="hide"
801
+
802
+ # Double click to hide legend
803
+ toggle_legend_js = CustomJS(args=dict(leg=plot.legend[0]), code='''
804
+ if (leg.visible) {
805
+ leg.visible = false
806
+ }
807
+ else {
808
+ leg.visible = true
809
+ }
810
+ ''')
811
+
812
+ plot.js_on_event(events.DoubleTap, toggle_legend_js)
813
+ else:
814
+ return None
815
+
816
+ if source!=None:
817
+ output_file(f'{source}_sed.html')
818
+
819
+ elif pos!=None:
820
+ if pos[1]>=0:
821
+ output_file(f"{pos[0]}+{pos[1]}_sed.html")
822
+ else:
823
+ output_file(f"{pos[0]}{pos[1]}_sed.html")
824
+
825
+ return plot
826
+
827
+ # Spectra Queries --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
828
+
829
+ def getsdssspectrum(source=None,pos=None,radius=3):
830
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
831
+ from .Surveys.SDSS import get_plot
832
+
833
+ if source!=None and pos!=None:
834
+ raise Exception('simulatenous source and pos input detected')
835
+
836
+ if source!=None:
837
+ gaia_data=gaiaquery(source=source)
838
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
839
+
840
+ pos_corrected=CorrectPM([2016,0],[2017,0],ra,dec,pmra,pmdec)
841
+ ra,dec=pos_corrected[0],pos_corrected[1]
842
+ elif pos!=None:
843
+ ra,dec=pos[0],pos[1]
844
+ else:
845
+ raise Exception('either source or pos input required')
846
+ return None
847
+
848
+ plot=get_plot(ra=ra,dec=dec,radius=radius)
849
+
850
+ if source!=None:
851
+ output_file(f'{source}_spectrum.html')
852
+
853
+ elif pos!=None:
854
+ if pos[1]>=0:
855
+ output_file(f"{pos[0]}+{pos[1]}_spectrum.html")
856
+ else:
857
+ output_file(f"{pos[0]}{pos[1]}_spectrum.html")
858
+
859
+ return plot
860
+
861
+ # HR diagram --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
862
+
863
+ def gethrd(source=None,sources=None):
864
+ from .Figures.HRD import get_plot
865
+ if source==None and sources==None:
866
+ raise Exception('source/sources input required')
867
+ return None
868
+
869
+ if source!=None:
870
+ plot=get_plot(source=source)
871
+ elif sources!=None:
872
+ plot=get_plot(sources=sources)
873
+ else:
874
+ raise Exception('source/sources input required.')
875
+
876
+ if plot!=None:
877
+ # Double click to hide legend
878
+ toggle_legend_js = CustomJS(args=dict(leg=plot.legend[0]), code='''
879
+ if (leg.visible) {
880
+ leg.visible = false
881
+ }
882
+ else {
883
+ leg.visible = true
884
+ }
885
+ ''')
886
+
887
+ plot.js_on_event(events.DoubleTap, toggle_legend_js)
888
+
889
+ if source!=None:
890
+ output_file(f'{source}_hrd.html')
891
+ elif sources==None:
892
+ sources_str=''
893
+ for i in range(0,len(sources)-1):
894
+ sources_str.append(str(sources[i]))+','
895
+ sources_str.append(source[len(source)-1])
896
+ output_file(f'{sources}_hrd.html')
897
+
898
+ return plot
899
+
900
+ # Timeseries analysis -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
901
+
902
+ def getztfanalysis(source=None,pos=None):
903
+ from .Timeseries.ztfanalysis import getanalysis
904
+
905
+ if pos!=None:
906
+ data=ztfquery(pos=pos)
907
+ elif source!=None:
908
+ data=ztfquery(source=source)
909
+ else:
910
+ raise Exception('either source or pos input required')
911
+ return None
912
+
913
+ empty_count=0
914
+ for item in data:
915
+ if not isinstance(item,pd.DataFrame):
916
+ empty_count+=1
917
+
918
+ if empty_count!=3:
919
+ data=pd.concat(data)
920
+ else:
921
+ print('no ZTF data available for given fields')
922
+ return None
923
+
924
+ getanalysis(data)
925
+
926
+ def getps(source=None,pos=None):
927
+ from .Timeseries.ztfanalysis import getpowerspectrum
928
+
929
+ if pos!=None:
930
+ data=ztfquery(pos=pos)
931
+ elif source!=None:
932
+ data=ztfquery(source=source)
933
+ else:
934
+ raise Exception('either source or pos input required')
935
+
936
+ empty_count=0
937
+ for item in data:
938
+ if not isinstance(item,pd.DataFrame):
939
+ empty_count+=1
940
+
941
+ if empty_count!=3:
942
+ data=pd.concat(data)
943
+ else:
944
+ print('no ZTF data available for given fields')
945
+ return None
946
+
947
+ plot=getpowerspectrum(data)
948
+
949
+ if source!=None:
950
+ output_file(f'{source}_powspec.html')
951
+
952
+ elif pos!=None:
953
+ if pos[1]>=0:
954
+ output_file(f"{pos[0]}+{pos[1]}_powspec.html")
955
+ else:
956
+ output_file(f"{pos[0]}{pos[1]}_powspec.html")
957
+
958
+ return plot
959
+
960
+ # Miscellaneous Tools -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
961
+
962
+ def correctPM(input,target,ra,dec,pmra,pmdec):
963
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
964
+
965
+ data=CorrectPM(input,target,ra,dec,pmra,pmdec)
966
+ return data
967
+
968
+ def getgaiacoords(source,catalogue='dr3'):
969
+ from .Surveys.Gaia import GaiaGetCoords
970
+
971
+ data=GaiaGetCoords(source,catalogue)
972
+ return data
973
+
974
+ def getgaiasource(pos,radius=3,catalogue='dr3'):
975
+ from .Surveys.Gaia import GaiaGetDesignation
976
+
977
+ ra,dec=pos[0],pos[1]
978
+ data=GaiaGetDesignation(ra,dec,radius,catalogue)
979
+ return data
980
+
981
+ def getsources(file_name):
982
+ from .Miscellaneous.ReadFits import get_source_list
983
+
984
+ sources=get_source_list(file_name)
985
+ return sources
986
+
987
+ def getpositions(file_name):
988
+ from .Miscellaneous.ReadFits import get_pos_list
989
+ pos_list=get_pos_list(file_name)
990
+ return pos_list
991
+
992
+ # Datapage generation -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
993
+
994
+ def getdatapage(source=None,pos=None,prefs=None):
995
+ from .Miscellaneous.ProperMotionCorrection import PMCorrection as CorrectPM
996
+
997
+ if isinstance(prefs,dict):
998
+ keys=prefs.keys()
999
+ if 'band' in keys:
1000
+ band=prefs['band']
1001
+ else:
1002
+ band='g'
1003
+ if 'overlay' in keys:
1004
+ overlay=prefs['overlay']
1005
+ else:
1006
+ overlay=['gaia']
1007
+ if 'image_size' in keys:
1008
+ image_size=prefs['image_size']
1009
+ else:
1010
+ image_size=20
1011
+ if 'lc_radius' in keys:
1012
+ lc_radius=prefs['lc_radius']
1013
+ else:
1014
+ lc_radius=3
1015
+ if 'sed_radius' in keys:
1016
+ sed_radius=prefs['sed_radius']
1017
+ else:
1018
+ sed_radius=3
1019
+ if 'spec_radius' in keys:
1020
+ spec_radius=prefs['spec_radius']
1021
+ else:
1022
+ spec_radius=3
1023
+ if 'simbad_radius' in keys:
1024
+ simbad_radius=prefs['simbad_radius']
1025
+ else:
1026
+ simbad_radius=3
1027
+ if 'vizier_radius' in keys:
1028
+ vizier_radius_override=prefs['vizier_radius']
1029
+ else:
1030
+ vizier_radius_override=None
1031
+ if 'grid_size' in keys:
1032
+ grid_size_override=prefs['grid_size']
1033
+ else:
1034
+ grid_size_override=300
1035
+
1036
+ else:
1037
+ band='g'
1038
+ overlay=['gaia']
1039
+ image_size=20
1040
+ lc_radius=3
1041
+ sed_radius=3
1042
+ spec_radius=3
1043
+ simbad_radius=3
1044
+ vizier_radius_override=None
1045
+ grid_size_override=300
1046
+
1047
+ if source!=None and pos!=None:
1048
+ raise Exception('simulatenous source and pos input detected')
1049
+
1050
+ if source!=None:
1051
+ gaia_data=gaiaquery(source=source)
1052
+ ra,dec,pmra,pmdec=gaia_data['ra'].values[0],gaia_data['dec'].values[0],gaia_data['pmra'].values[0],gaia_data['pmdec'].values[0]
1053
+
1054
+ pos_corrected=correctPM([2016,0],[2012,0],ra,dec,pmra,pmdec)
1055
+ ra_panstarrs,dec_panstarrs=pos_corrected[0],pos_corrected[1]
1056
+
1057
+ pos_corrected=correctPM([2016,0],[2016,0],ra,dec,pmra,pmdec)
1058
+ ra_skymapper,dec_skymapper=pos_corrected[0],pos_corrected[1]
1059
+
1060
+ ra_gaia,dec_gaia=ra,dec
1061
+
1062
+ pos_corrected=correctPM([2016,0],[2007,0],ra,dec,pmra,pmdec)
1063
+ ra_galex,dec_galex=pos_corrected[0],pos_corrected[1]
1064
+
1065
+ pos_corrected=correctPM([2016,0],[1991,0],ra,dec,pmra,pmdec)
1066
+ ra_rosat,dec_rosat=pos_corrected[0],pos_corrected[1]
1067
+
1068
+ pos_corrected=correctPM([2016,0],[2019,0],ra,dec,pmra,pmdec)
1069
+ ra_ztf,dec_ztf=pos_corrected[0],pos_corrected[1]
1070
+
1071
+ pos_corrected=correctPM([2016,0],[2017,0],ra,dec,pmra,pmdec)
1072
+ ra_sdss,dec_sdss=pos_corrected[0],pos_corrected[1]
1073
+
1074
+ elif pos!=None:
1075
+ ra,dec=pos[0],pos[1]
1076
+ ra_panstarrs,dec_panstarrs=pos[0],pos[1]
1077
+ ra_skymapper,dec_skymapper=pos[0],pos[1]
1078
+ ra_gaia,dec_gaia=pos[0],pos[1]
1079
+ ra_galex,dec_galex=pos[0],pos[1]
1080
+ ra_rosat,dec_rosat=pos[0],pos[1]
1081
+ ra_ztf,dec_ztf=pos[0],pos[1]
1082
+ ra_sdss,dec_sdss=pos[0],pos[1]
1083
+ else:
1084
+ raise Exception('either source or pos input required')
1085
+
1086
+ # Need to add in 'prefs' parameters
1087
+ if source!=None:
1088
+ lightcurve_axis_g,lightcurve_axis_r,lightcurve_axis_i=getztflc(source=source,return_raw=True,radius=lc_radius)
1089
+ hrd_axis=gethrd(source=source)
1090
+ sed_axis=getsed(source=source,radius=sed_radius)
1091
+ spectrum_axis=getsdssspectrum(source=source,radius=spec_radius)
1092
+ image_axis,image_time=getpanstarrsimage(source=source,get_time=True,band=band,overlay=overlay,image_size=image_size)
1093
+ if image_axis==None:
1094
+ image_axis,image_time=getskymapperimage(source=source,get_time=True,band=band,overlay=overlay,image_size=image_size)
1095
+ if image_axis==None:
1096
+ image_axis,image_time=getdssimage(source=source,get_time=True,overlay=overlay,image_size=image_size)
1097
+ ps_axis=getps(source=source)
1098
+
1099
+ output_file(f"{source}_datapage.html")
1100
+
1101
+ elif pos!=None:
1102
+ lightcurve_axis_g,lightcurve_axis_r,lightcurve_axis_i=getztflc(pos=pos,return_raw=True,radius=lc_radius)
1103
+ hrd_axis=None
1104
+ sed_axis=getsed(pos=pos,radius=sed_radius)
1105
+ spectrum_axis=getsdssspectrum(pos=pos,radius=spec_radius)
1106
+ image_axis,image_time=getpanstarrsimage(pos=pos,get_time=True,band=band,overlay=overlay,image_size=image_size)
1107
+ if image_axis==None:
1108
+ image_axis,image_time=getskymapperimage(pos=pos,get_time=True,band=band,overlay=overlay,image_size=image_size)
1109
+ if image_axis==None:
1110
+ image_axis,image_time=getdssimage(pos=pos,get_time=True,overlay=overlay,image_size=image_size)
1111
+ ps_axis=getps(pos=pos)
1112
+
1113
+ if pos[1]>=0:
1114
+ output_file(f"{pos[0]}+{pos[1]}_datapage.html")
1115
+ else:
1116
+ output_file(f"{pos[0]}{pos[1]}_datapage.html")
1117
+
1118
+ button_width=100
1119
+ button_height=25
1120
+
1121
+ # SIMBAD button
1122
+ simbad_button = Button(label="SIMBAD",button_type='primary',height=button_height,width=button_width)
1123
+
1124
+ if pos!=None:
1125
+ simbad_url=f'https://simbad.cds.unistra.fr/simbad/sim-coo?Coord={ra}+{dec}&CooFrame=FK5&CooEpoch=2000&CooEqui=2000&CooDefinedFrames=none&Radius={simbad_radius}&Radius.unit=arcsec&submit=submit+query&CoordList='
1126
+ elif source!=None:
1127
+ simbad_url=f'http://simbad.u-strasbg.fr/simbad/sim-id?Ident=Gaia DR3 {source}&NbIdent=1&Radius={simbad_radius}&Radius.unit=arcsec&submit=submit+id'
1128
+
1129
+ simbad_button_js = CustomJS(args=dict(url=simbad_url),code='''
1130
+ window.open(url)
1131
+ ''')
1132
+ simbad_button.js_on_event('button_click',simbad_button_js)
1133
+
1134
+ # Vizier button
1135
+ # Scale vizier search radius and coordinates with proper motion if available
1136
+ if source!=None:
1137
+ if isinstance(image_time,list):
1138
+ gaia_time=[2016,0]
1139
+ vizier_ra,vizier_dec,vizier_radius=CorrectPM(gaia_time,image_time,ra_gaia,dec_gaia,pmra,pmdec,radius=image_size)
1140
+ else:
1141
+ vizier_ra,vizier_dec,vizier_radius=ra,dec,image_size
1142
+ elif pos!=None:
1143
+ vizier_ra,vizier_dec,vizier_radius=pos[0],pos[1],image_size
1144
+
1145
+ # Allows search radius to be overriden by prefs
1146
+ if vizier_radius_override!=None:
1147
+ vizier_radius=vizier_radius_override
1148
+
1149
+ vizier_button = Button(label="Vizier",button_type='primary',height=button_height,width=button_width)
1150
+
1151
+ vizier_url=f'https://vizier.cds.unistra.fr/viz-bin/VizieR-4?-c={vizier_ra}%2b{vizier_dec}&-c.rs={vizier_radius}&-out.add=_r&-sort=_r&-out.max=$4'
1152
+
1153
+ vizier_button_js = CustomJS(args=dict(url=vizier_url),code='''
1154
+ window.open(url)
1155
+ ''')
1156
+ vizier_button.js_on_event('button_click',vizier_button_js)
1157
+
1158
+ # Set up grid and button dimensions
1159
+ grid_size=grid_size_override
1160
+
1161
+ # Empirical relation that roughly works
1162
+ left_offset=round((0.25+((300-grid_size)/1000))*grid_size)
1163
+
1164
+ # Margin = [Top,Right,Bottom,Left]
1165
+ simbad_button.margin=[round(0.1*(grid_size-button_height)),0,0,left_offset]
1166
+ vizier_button.margin=[round(0.05*(grid_size-button_height)),0,0,left_offset]
1167
+
1168
+ simbad_button.width,simbad_button.height=round(0.6*grid_size),round(0.15*grid_size)
1169
+ vizier_button.width,vizier_button.height=round(0.6*grid_size),round(0.15*grid_size)
1170
+
1171
+ # layout doesn't allow None
1172
+ if image_axis==None:
1173
+ image_axis=figure()
1174
+ if lightcurve_axis_g==None:
1175
+ lightcurve_axis_g=figure()
1176
+ if lightcurve_axis_r==None:
1177
+ lightcurve_axis_r=figure()
1178
+ if lightcurve_axis_i==None:
1179
+ lightcurve_axis_i=figure()
1180
+ if sed_axis==None:
1181
+ sed_axis=figure()
1182
+ if hrd_axis==None:
1183
+ hrd_axis=figure()
1184
+ if spectrum_axis==None:
1185
+ spectrum_axis=figure()
1186
+ if ps_axis==None:
1187
+ ps_axis=figure()
1188
+
1189
+ buttons=column(simbad_button,vizier_button,align='center')
1190
+
1191
+ image_axis.width,image_axis.height=2*grid_size,2*grid_size
1192
+ buttons.width,buttons.height=grid_size,grid_size
1193
+ lightcurve_axis_g.width,lightcurve_axis_g.height=grid_size,grid_size
1194
+
1195
+ hrd_axis.width,hrd_axis.height=2*grid_size,2*grid_size
1196
+ lightcurve_axis_r.width,lightcurve_axis_r.height=grid_size,grid_size
1197
+ lightcurve_axis_i.width,lightcurve_axis_i.height=grid_size,grid_size
1198
+
1199
+ sed_axis.width,sed_axis.height=2*grid_size,grid_size
1200
+ spectrum_axis.width,spectrum_axis.height=2*grid_size,grid_size
1201
+ ps_axis.width,ps_axis.height=2*grid_size,grid_size
1202
+
1203
+ grid=layout(row(
1204
+ column([image_axis,row(buttons,lightcurve_axis_g)]),
1205
+ column([hrd_axis,row(lightcurve_axis_r,lightcurve_axis_i)]),
1206
+ column([sed_axis,spectrum_axis,ps_axis])
1207
+ ))
1208
+
1209
+ '''
1210
+ def exec_timeseries(event):
1211
+ sys_path=os.getcwd()
1212
+ timeseries_path=os.path.join(sys_path,'timeseries.py')
1213
+ print(timeseries_path)
1214
+ if source!=None:
1215
+ subprocess.run(['python',timeseries_path,'source',str(source)])
1216
+ elif pos!=None:
1217
+ subprocess.run(['python',timeseries_path,'pos',str(pos[0]),str(pos[1])])
1218
+
1219
+ timeseries_button.on_event('button_click',exec_timeseries)
1220
+ '''
1221
+
1222
+ return grid