astro-otter 0.0.1__tar.gz → 0.0.2__tar.gz
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.
Potentially problematic release.
This version of astro-otter might be problematic. Click here for more details.
- {astro_otter-0.0.1/src/astro_otter.egg-info → astro_otter-0.0.2}/PKG-INFO +13 -4
- {astro_otter-0.0.1 → astro_otter-0.0.2}/README.md +5 -3
- {astro_otter-0.0.1 → astro_otter-0.0.2}/pyproject.toml +11 -2
- {astro_otter-0.0.1 → astro_otter-0.0.2/src/astro_otter.egg-info}/PKG-INFO +13 -4
- {astro_otter-0.0.1 → astro_otter-0.0.2}/src/astro_otter.egg-info/SOURCES.txt +4 -1
- astro_otter-0.0.2/src/astro_otter.egg-info/requires.txt +17 -0
- {astro_otter-0.0.1 → astro_otter-0.0.2}/src/otter/__init__.py +2 -0
- {astro_otter-0.0.1 → astro_otter-0.0.2}/src/otter/_version.py +1 -1
- {astro_otter-0.0.1 → astro_otter-0.0.2}/src/otter/exceptions.py +19 -0
- {astro_otter-0.0.1 → astro_otter-0.0.2}/src/otter/io/otter.py +71 -53
- {astro_otter-0.0.1 → astro_otter-0.0.2}/src/otter/io/transient.py +60 -11
- {astro_otter-0.0.1 → astro_otter-0.0.2}/src/otter/plotter/otter_plotter.py +10 -8
- {astro_otter-0.0.1 → astro_otter-0.0.2}/src/otter/plotter/plotter.py +19 -18
- {astro_otter-0.0.1 → astro_otter-0.0.2}/src/otter/util.py +60 -1
- astro_otter-0.0.2/tests/test_exceptions.py +33 -0
- astro_otter-0.0.2/tests/test_otter.py +227 -0
- {astro_otter-0.0.1 → astro_otter-0.0.2}/tests/test_transient.py +168 -1
- astro_otter-0.0.2/tests/test_util.py +44 -0
- astro_otter-0.0.1/src/astro_otter.egg-info/requires.txt +0 -10
- {astro_otter-0.0.1 → astro_otter-0.0.2}/LICENSE +0 -0
- {astro_otter-0.0.1 → astro_otter-0.0.2}/setup.cfg +0 -0
- {astro_otter-0.0.1 → astro_otter-0.0.2}/src/astro_otter.egg-info/dependency_links.txt +0 -0
- {astro_otter-0.0.1 → astro_otter-0.0.2}/src/astro_otter.egg-info/top_level.txt +0 -0
- {astro_otter-0.0.1 → astro_otter-0.0.2}/src/otter/io/__init__.py +0 -0
- {astro_otter-0.0.1 → astro_otter-0.0.2}/src/otter/plotter/__init__.py +0 -0
- {astro_otter-0.0.1 → astro_otter-0.0.2}/tests/test_package.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: astro-otter
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.2
|
|
4
4
|
Author-email: Noah Franz <nfranz@arizona.edu>
|
|
5
5
|
License: MIT License
|
|
6
6
|
|
|
@@ -50,6 +50,13 @@ Requires-Dist: synphot
|
|
|
50
50
|
Requires-Dist: ads
|
|
51
51
|
Requires-Dist: ruff
|
|
52
52
|
Requires-Dist: pre-commit
|
|
53
|
+
Requires-Dist: Sphinx>=3.0.0
|
|
54
|
+
Requires-Dist: myst_parser>=0.13
|
|
55
|
+
Requires-Dist: nbsphinx>=0.9.1
|
|
56
|
+
Requires-Dist: sphinx-book-theme>=0.0.33
|
|
57
|
+
Requires-Dist: sphinx_copybutton
|
|
58
|
+
Requires-Dist: autodoc
|
|
59
|
+
Requires-Dist: ipykernel
|
|
53
60
|
|
|
54
61
|
# OTTER API
|
|
55
62
|
### **O**pen mul**T**iwavelength **T**ransient **E**vent **R**epository
|
|
@@ -66,9 +73,9 @@ A Python API for the OTTER.
|
|
|
66
73
|
[github-discussions-link]: https://github.com/mattbellis/hepfile/discussions
|
|
67
74
|
[gitter-badge]: https://badges.gitter.im/https://github.com/mattbellis/hepfile/community.svg
|
|
68
75
|
[gitter-link]: https://gitter.im/https://github.com/mattbellis/hepfile/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
|
|
69
|
-
[pypi-link]: https://pypi.org/project/
|
|
70
|
-
[pypi-platforms]: https://img.shields.io/pypi/pyversions/
|
|
71
|
-
[pypi-version]: https://badge.fury.io/py/
|
|
76
|
+
[pypi-link]: https://pypi.org/project/astro-otter/
|
|
77
|
+
[pypi-platforms]: https://img.shields.io/pypi/pyversions/astro-otter
|
|
78
|
+
[pypi-version]: https://badge.fury.io/py/astro-otter.svg
|
|
72
79
|
[rtd-badge]: https://readthedocs.org/projects/otter/badge/?version=latest
|
|
73
80
|
[rtd-link]: https://otter.readthedocs.io/en/latest/?badge=latest
|
|
74
81
|
[sk-badge]: https://scikit-hep.org/assets/images/Scikit--HEP-Project-blue.svg
|
|
@@ -77,7 +84,9 @@ A Python API for the OTTER.
|
|
|
77
84
|
[codecov-badge]: https://codecov.io/gh/astro-otter/otter/graph/badge.svg?token=BtCerOdTc0
|
|
78
85
|
[codecov-link]: https://codecov.io/gh/astro-otter/otter
|
|
79
86
|
|
|
87
|
+
[](https://astro-otter.readthedocs.io/en/latest/?badge=latest)
|
|
80
88
|
[![Actions Status][actions-badge]][actions-link]
|
|
89
|
+
[![PyPI version][pypi-version]][pypi-link]
|
|
81
90
|
[![Linting: Ruff][ruff-badge]][ruff-link]
|
|
82
91
|
[![codecov][codecov-badge]][codecov-link]
|
|
83
92
|
|
|
@@ -13,9 +13,9 @@ A Python API for the OTTER.
|
|
|
13
13
|
[github-discussions-link]: https://github.com/mattbellis/hepfile/discussions
|
|
14
14
|
[gitter-badge]: https://badges.gitter.im/https://github.com/mattbellis/hepfile/community.svg
|
|
15
15
|
[gitter-link]: https://gitter.im/https://github.com/mattbellis/hepfile/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
|
|
16
|
-
[pypi-link]: https://pypi.org/project/
|
|
17
|
-
[pypi-platforms]: https://img.shields.io/pypi/pyversions/
|
|
18
|
-
[pypi-version]: https://badge.fury.io/py/
|
|
16
|
+
[pypi-link]: https://pypi.org/project/astro-otter/
|
|
17
|
+
[pypi-platforms]: https://img.shields.io/pypi/pyversions/astro-otter
|
|
18
|
+
[pypi-version]: https://badge.fury.io/py/astro-otter.svg
|
|
19
19
|
[rtd-badge]: https://readthedocs.org/projects/otter/badge/?version=latest
|
|
20
20
|
[rtd-link]: https://otter.readthedocs.io/en/latest/?badge=latest
|
|
21
21
|
[sk-badge]: https://scikit-hep.org/assets/images/Scikit--HEP-Project-blue.svg
|
|
@@ -24,7 +24,9 @@ A Python API for the OTTER.
|
|
|
24
24
|
[codecov-badge]: https://codecov.io/gh/astro-otter/otter/graph/badge.svg?token=BtCerOdTc0
|
|
25
25
|
[codecov-link]: https://codecov.io/gh/astro-otter/otter
|
|
26
26
|
|
|
27
|
+
[](https://astro-otter.readthedocs.io/en/latest/?badge=latest)
|
|
27
28
|
[![Actions Status][actions-badge]][actions-link]
|
|
29
|
+
[![PyPI version][pypi-version]][pypi-link]
|
|
28
30
|
[![Linting: Ruff][ruff-badge]][ruff-link]
|
|
29
31
|
[![codecov][codecov-badge]][codecov-link]
|
|
30
32
|
|
|
@@ -39,8 +39,17 @@ dependencies = [
|
|
|
39
39
|
|
|
40
40
|
# useful dev tools
|
|
41
41
|
"ruff", # linter
|
|
42
|
-
"pre-commit" # enable pre-commit hooks
|
|
43
|
-
|
|
42
|
+
"pre-commit", # enable pre-commit hooks
|
|
43
|
+
|
|
44
|
+
# tools for building the readthedocs page
|
|
45
|
+
"Sphinx>=3.0.0",
|
|
46
|
+
"myst_parser>=0.13",
|
|
47
|
+
"nbsphinx>=0.9.1",
|
|
48
|
+
"sphinx-book-theme>=0.0.33",
|
|
49
|
+
"sphinx_copybutton",
|
|
50
|
+
"autodoc",
|
|
51
|
+
"ipykernel"
|
|
52
|
+
]
|
|
44
53
|
|
|
45
54
|
[project.urls]
|
|
46
55
|
Home = "https://github.com/astro-otter"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: astro-otter
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.2
|
|
4
4
|
Author-email: Noah Franz <nfranz@arizona.edu>
|
|
5
5
|
License: MIT License
|
|
6
6
|
|
|
@@ -50,6 +50,13 @@ Requires-Dist: synphot
|
|
|
50
50
|
Requires-Dist: ads
|
|
51
51
|
Requires-Dist: ruff
|
|
52
52
|
Requires-Dist: pre-commit
|
|
53
|
+
Requires-Dist: Sphinx>=3.0.0
|
|
54
|
+
Requires-Dist: myst_parser>=0.13
|
|
55
|
+
Requires-Dist: nbsphinx>=0.9.1
|
|
56
|
+
Requires-Dist: sphinx-book-theme>=0.0.33
|
|
57
|
+
Requires-Dist: sphinx_copybutton
|
|
58
|
+
Requires-Dist: autodoc
|
|
59
|
+
Requires-Dist: ipykernel
|
|
53
60
|
|
|
54
61
|
# OTTER API
|
|
55
62
|
### **O**pen mul**T**iwavelength **T**ransient **E**vent **R**epository
|
|
@@ -66,9 +73,9 @@ A Python API for the OTTER.
|
|
|
66
73
|
[github-discussions-link]: https://github.com/mattbellis/hepfile/discussions
|
|
67
74
|
[gitter-badge]: https://badges.gitter.im/https://github.com/mattbellis/hepfile/community.svg
|
|
68
75
|
[gitter-link]: https://gitter.im/https://github.com/mattbellis/hepfile/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
|
|
69
|
-
[pypi-link]: https://pypi.org/project/
|
|
70
|
-
[pypi-platforms]: https://img.shields.io/pypi/pyversions/
|
|
71
|
-
[pypi-version]: https://badge.fury.io/py/
|
|
76
|
+
[pypi-link]: https://pypi.org/project/astro-otter/
|
|
77
|
+
[pypi-platforms]: https://img.shields.io/pypi/pyversions/astro-otter
|
|
78
|
+
[pypi-version]: https://badge.fury.io/py/astro-otter.svg
|
|
72
79
|
[rtd-badge]: https://readthedocs.org/projects/otter/badge/?version=latest
|
|
73
80
|
[rtd-link]: https://otter.readthedocs.io/en/latest/?badge=latest
|
|
74
81
|
[sk-badge]: https://scikit-hep.org/assets/images/Scikit--HEP-Project-blue.svg
|
|
@@ -77,7 +84,9 @@ A Python API for the OTTER.
|
|
|
77
84
|
[codecov-badge]: https://codecov.io/gh/astro-otter/otter/graph/badge.svg?token=BtCerOdTc0
|
|
78
85
|
[codecov-link]: https://codecov.io/gh/astro-otter/otter
|
|
79
86
|
|
|
87
|
+
[](https://astro-otter.readthedocs.io/en/latest/?badge=latest)
|
|
80
88
|
[![Actions Status][actions-badge]][actions-link]
|
|
89
|
+
[![PyPI version][pypi-version]][pypi-link]
|
|
81
90
|
[![Linting: Ruff][ruff-badge]][ruff-link]
|
|
82
91
|
[![codecov][codecov-badge]][codecov-link]
|
|
83
92
|
|
|
@@ -16,5 +16,8 @@ src/otter/io/transient.py
|
|
|
16
16
|
src/otter/plotter/__init__.py
|
|
17
17
|
src/otter/plotter/otter_plotter.py
|
|
18
18
|
src/otter/plotter/plotter.py
|
|
19
|
+
tests/test_exceptions.py
|
|
20
|
+
tests/test_otter.py
|
|
19
21
|
tests/test_package.py
|
|
20
|
-
tests/test_transient.py
|
|
22
|
+
tests/test_transient.py
|
|
23
|
+
tests/test_util.py
|
|
@@ -2,8 +2,14 @@
|
|
|
2
2
|
Custom exceptions for otter
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
5
7
|
|
|
6
8
|
class FailedQueryError(ValueError):
|
|
9
|
+
"""
|
|
10
|
+
Exception thrown when the users query does not return any results.
|
|
11
|
+
"""
|
|
12
|
+
|
|
7
13
|
def __str__(self):
|
|
8
14
|
txt = "You're query/search did not return any results! "
|
|
9
15
|
txt += "Try again with different parameters!"
|
|
@@ -11,10 +17,19 @@ class FailedQueryError(ValueError):
|
|
|
11
17
|
|
|
12
18
|
|
|
13
19
|
class IOError(ValueError):
|
|
20
|
+
"""
|
|
21
|
+
Exception thrown when the input or output argument/value is not the correct type.
|
|
22
|
+
"""
|
|
23
|
+
|
|
14
24
|
pass
|
|
15
25
|
|
|
16
26
|
|
|
17
27
|
class OtterLimitationError(Exception):
|
|
28
|
+
"""
|
|
29
|
+
Exception thrown when the user requests something that is currently not supported
|
|
30
|
+
by the API.
|
|
31
|
+
"""
|
|
32
|
+
|
|
18
33
|
def __init__(self, msg):
|
|
19
34
|
self.msg = "Current Limitation Found: " + msg
|
|
20
35
|
|
|
@@ -23,4 +38,8 @@ class OtterLimitationError(Exception):
|
|
|
23
38
|
|
|
24
39
|
|
|
25
40
|
class TransientMergeError(Exception):
|
|
41
|
+
"""
|
|
42
|
+
Exception thrown when the Transient objects can not be combined as expected.
|
|
43
|
+
"""
|
|
44
|
+
|
|
26
45
|
pass
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
This is the primary class for user interaction with the catalog
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from __future__ import annotations
|
|
5
6
|
import os
|
|
6
7
|
import json
|
|
7
8
|
import glob
|
|
@@ -28,14 +29,11 @@ class Otter(object):
|
|
|
28
29
|
This is the primary class for users to access the otter backend database
|
|
29
30
|
|
|
30
31
|
Args:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
collection [str]: The collection to read data from. Right now the only
|
|
37
|
-
collection is 'tdes'.
|
|
38
|
-
debug [bool]: debug mode, set to true to limit reading from database.
|
|
32
|
+
datadir (str): Path to the data directory with the otter data. If not provided
|
|
33
|
+
will default to a ".otter" directory in the CWD where you call
|
|
34
|
+
this class from.
|
|
35
|
+
debug (bool): If we should just debug and not do anything serious.
|
|
36
|
+
|
|
39
37
|
"""
|
|
40
38
|
|
|
41
39
|
def __init__(self, datadir: str = None, debug: bool = False) -> None:
|
|
@@ -87,9 +85,9 @@ class Otter(object):
|
|
|
87
85
|
Performs a cone search of the catalog over the given coords and radius.
|
|
88
86
|
|
|
89
87
|
Args:
|
|
90
|
-
coords
|
|
91
|
-
radius
|
|
92
|
-
raw
|
|
88
|
+
coords (SkyCoord): An astropy SkyCoord object with coordinates to match to
|
|
89
|
+
radius (float): The radius of the cone in arcseconds, default is 0.05"
|
|
90
|
+
raw (bool): If False (the default) return an astropy table of the metadata
|
|
93
91
|
for matching objects. Otherwise, return the raw json dicts
|
|
94
92
|
|
|
95
93
|
Return:
|
|
@@ -117,35 +115,40 @@ class Otter(object):
|
|
|
117
115
|
unit conversion for you!
|
|
118
116
|
|
|
119
117
|
Args:
|
|
120
|
-
flux_units
|
|
118
|
+
flux_units (astropy.unit.Unit): Either a valid string to convert
|
|
121
119
|
or an astropy.unit.Unit
|
|
122
|
-
date_units
|
|
120
|
+
date_units (astropy.unit.Unit): Either a valid string to convert to a date
|
|
123
121
|
or an astropy.unit.Unit
|
|
124
|
-
return_type
|
|
122
|
+
return_type (str): Either 'astropy' or 'pandas'. If astropy, returns an
|
|
125
123
|
astropy Table. If pandas, returns a pandas DataFrame.
|
|
126
124
|
Default is 'astropy'.
|
|
127
|
-
obs_type
|
|
125
|
+
obs_type (str): Either 'radio', 'uvoir', or 'xray'. Will only return that
|
|
128
126
|
type of photometry if not None. Default is None and will
|
|
129
127
|
return any type of photometry.
|
|
130
|
-
keep_raw
|
|
128
|
+
keep_raw (bool): If True, keep the raw flux/date/freq/wave associated with
|
|
131
129
|
the dataset. Else, just keep the converted data. Default
|
|
132
130
|
is False.
|
|
133
|
-
**kwargs : Arguments to pass to Otter.query(). Can be
|
|
134
|
-
|
|
135
|
-
|
|
131
|
+
**kwargs : Arguments to pass to Otter.query(). Can be::
|
|
132
|
+
|
|
133
|
+
names (list[str]): A list of names to get the metadata for
|
|
134
|
+
coords (SkyCoord): An astropy SkyCoord object with coordinates
|
|
136
135
|
to match to
|
|
137
|
-
radius
|
|
136
|
+
radius (float): The radius in arcseconds for a cone search,
|
|
138
137
|
default is 0.05"
|
|
139
|
-
minZ
|
|
140
|
-
maxZ
|
|
141
|
-
refs
|
|
138
|
+
minZ (float): The minimum redshift to search for
|
|
139
|
+
maxZ (float): The maximum redshift to search for
|
|
140
|
+
refs (list[str]): A list of ads bibcodes to match to. Will only
|
|
142
141
|
return metadata for transients that have this
|
|
143
142
|
as a reference.
|
|
144
|
-
hasSpec
|
|
143
|
+
hasSpec (bool): if True, only return events that have spectra.
|
|
145
144
|
|
|
146
145
|
Return:
|
|
147
|
-
|
|
148
|
-
|
|
146
|
+
The photometry for the requested transients that match the arguments.
|
|
147
|
+
Will be an astropy Table sorted by transient default name.
|
|
148
|
+
|
|
149
|
+
Raises:
|
|
150
|
+
FailedQueryError: When the query returns no results
|
|
151
|
+
IOError: if one of your inputs is incorrect
|
|
149
152
|
"""
|
|
150
153
|
queryres = self.query(hasphot=True, **kwargs)
|
|
151
154
|
|
|
@@ -153,16 +156,25 @@ class Otter(object):
|
|
|
153
156
|
for transient in queryres:
|
|
154
157
|
# clean the photometry
|
|
155
158
|
default_name = transient["name/default_name"]
|
|
156
|
-
phot = transient.clean_photometry(
|
|
157
|
-
flux_unit=flux_unit,
|
|
158
|
-
date_unit=date_unit,
|
|
159
|
-
wave_unit=wave_unit,
|
|
160
|
-
freq_unit=freq_unit,
|
|
161
|
-
obs_type=obs_type,
|
|
162
|
-
)
|
|
163
|
-
phot["name"] = [default_name] * len(phot)
|
|
164
159
|
|
|
165
|
-
|
|
160
|
+
try:
|
|
161
|
+
phot = transient.clean_photometry(
|
|
162
|
+
flux_unit=flux_unit,
|
|
163
|
+
date_unit=date_unit,
|
|
164
|
+
wave_unit=wave_unit,
|
|
165
|
+
freq_unit=freq_unit,
|
|
166
|
+
obs_type=obs_type,
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
phot["name"] = [default_name] * len(phot)
|
|
170
|
+
|
|
171
|
+
dicts.append(phot)
|
|
172
|
+
|
|
173
|
+
except FailedQueryError:
|
|
174
|
+
# This is fine, it just means that there is no data associated
|
|
175
|
+
# with this one transient. We'll check and make sure there is data
|
|
176
|
+
# associated with at least one of the transients later!
|
|
177
|
+
pass
|
|
166
178
|
|
|
167
179
|
if len(dicts) == 0:
|
|
168
180
|
raise FailedQueryError()
|
|
@@ -203,7 +215,7 @@ class Otter(object):
|
|
|
203
215
|
Loads an otter JSON file
|
|
204
216
|
|
|
205
217
|
Args:
|
|
206
|
-
filename
|
|
218
|
+
filename (str): The path to the OTTER JSON file to load
|
|
207
219
|
"""
|
|
208
220
|
|
|
209
221
|
# read in files from summary
|
|
@@ -234,15 +246,15 @@ class Otter(object):
|
|
|
234
246
|
same units.
|
|
235
247
|
|
|
236
248
|
Args:
|
|
237
|
-
names
|
|
238
|
-
coords
|
|
239
|
-
radius
|
|
240
|
-
minz
|
|
241
|
-
maxz
|
|
242
|
-
refs
|
|
249
|
+
names (list[str]): A list of names to get the metadata for
|
|
250
|
+
coords (SkyCoord): An astropy SkyCoord object with coordinates to match to
|
|
251
|
+
radius (float): The radius in arcseconds for a cone search, default is 0.05"
|
|
252
|
+
minz (float): The minimum redshift to search for
|
|
253
|
+
maxz (float): The maximum redshift to search for
|
|
254
|
+
refs (list[str]): A list of ads bibcodes to match to. Will only return
|
|
243
255
|
metadata for transients that have this as a reference.
|
|
244
|
-
hasphot
|
|
245
|
-
hasspec
|
|
256
|
+
hasphot (bool): if True, only returns transients which have photometry.
|
|
257
|
+
hasspec (bool): if True, only return transients that have spectra.
|
|
246
258
|
|
|
247
259
|
Return:
|
|
248
260
|
Get all of the raw (unconverted!) data for objects that match the criteria.
|
|
@@ -344,24 +356,29 @@ class Otter(object):
|
|
|
344
356
|
|
|
345
357
|
return outdata
|
|
346
358
|
|
|
347
|
-
def save(self, schema: list[dict], testing=False
|
|
359
|
+
def save(self, schema: list[dict], testing=False) -> None:
|
|
348
360
|
"""
|
|
349
361
|
Upload all the data in the given list of schemas.
|
|
350
362
|
|
|
351
363
|
Args:
|
|
352
|
-
schema
|
|
364
|
+
schema (list[dict]): A list of json dictionaries
|
|
365
|
+
testing (bool): Should we just enter test mode? Default is False
|
|
366
|
+
|
|
367
|
+
Raises:
|
|
368
|
+
OtterLimitationError: If some objects in OTTER are within 5" we can't figure
|
|
369
|
+
out which ones to merge with which ones.
|
|
353
370
|
"""
|
|
354
371
|
|
|
355
372
|
if not isinstance(schema, list):
|
|
356
373
|
schema = [schema]
|
|
357
374
|
|
|
358
375
|
for transient in schema:
|
|
359
|
-
print(transient["name/default_name"])
|
|
360
|
-
|
|
361
376
|
# convert the json to a Transient
|
|
362
377
|
if not isinstance(transient, Transient):
|
|
363
378
|
transient = Transient(transient)
|
|
364
379
|
|
|
380
|
+
print(transient["name/default_name"])
|
|
381
|
+
|
|
365
382
|
coord = transient.get_skycoord()
|
|
366
383
|
res = self.cone_search(coords=coord)
|
|
367
384
|
|
|
@@ -405,8 +422,6 @@ class Otter(object):
|
|
|
405
422
|
outfilepath = os.path.join(self.DATADIR, todel[0] + ".json")
|
|
406
423
|
if test_mode:
|
|
407
424
|
print("Renaming the following file for backups: ", outfilepath)
|
|
408
|
-
else:
|
|
409
|
-
os.rename(outfilepath, outfilepath + ".backup")
|
|
410
425
|
else:
|
|
411
426
|
if test_mode:
|
|
412
427
|
print("Don't need to mess with the files at all!")
|
|
@@ -429,13 +444,16 @@ class Otter(object):
|
|
|
429
444
|
print(f"Would write to {outfilepath}")
|
|
430
445
|
# print(out)
|
|
431
446
|
|
|
432
|
-
def generate_summary_table(self, save=False):
|
|
447
|
+
def generate_summary_table(self, save=False) -> pd.DataFrame:
|
|
433
448
|
"""
|
|
434
449
|
Generate a summary table for the JSON files in self.DATADIR
|
|
435
450
|
|
|
436
451
|
args:
|
|
437
|
-
save
|
|
438
|
-
in self.DATADIR. Default is False.
|
|
452
|
+
save (bool): if True, save the summary file to "summary.csv"
|
|
453
|
+
in self.DATADIR. Default is False and is just returned.
|
|
454
|
+
|
|
455
|
+
returns:
|
|
456
|
+
pandas.DataFrame of the summary meta information of the transients
|
|
439
457
|
"""
|
|
440
458
|
allfiles = glob.glob(os.path.join(self.DATADIR, "*.json"))
|
|
441
459
|
|
|
@@ -3,10 +3,12 @@ Class for a transient,
|
|
|
3
3
|
basically just inherits the dict properties with some overwriting
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
+
from __future__ import annotations
|
|
6
7
|
import warnings
|
|
7
8
|
from copy import deepcopy
|
|
8
9
|
import re
|
|
9
10
|
from collections.abc import MutableMapping
|
|
11
|
+
from typing_extensions import Self
|
|
10
12
|
|
|
11
13
|
import numpy as np
|
|
12
14
|
import pandas as pd
|
|
@@ -37,7 +39,9 @@ class Transient(MutableMapping):
|
|
|
37
39
|
Overwrite the dictionary init
|
|
38
40
|
|
|
39
41
|
Args:
|
|
40
|
-
d
|
|
42
|
+
d (dict): A transient dictionary
|
|
43
|
+
name (str): The default name of the transient, default is None and it will
|
|
44
|
+
be inferred from the input dictionary.
|
|
41
45
|
"""
|
|
42
46
|
self.data = d
|
|
43
47
|
|
|
@@ -68,7 +72,7 @@ class Transient(MutableMapping):
|
|
|
68
72
|
"""
|
|
69
73
|
|
|
70
74
|
if isinstance(keys, (list, tuple)):
|
|
71
|
-
return Transient({key: self[key] for key in keys})
|
|
75
|
+
return Transient({key: (self[key] if key in self else []) for key in keys})
|
|
72
76
|
elif isinstance(keys, str) and "/" in keys: # this is for a path
|
|
73
77
|
s = "']['".join(keys.split("/"))
|
|
74
78
|
s = "['" + s
|
|
@@ -85,6 +89,10 @@ class Transient(MutableMapping):
|
|
|
85
89
|
return self.data[keys]
|
|
86
90
|
|
|
87
91
|
def __setitem__(self, key, value):
|
|
92
|
+
"""
|
|
93
|
+
Override set item to work with the '/' syntax
|
|
94
|
+
"""
|
|
95
|
+
|
|
88
96
|
if isinstance(key, str) and "/" in key: # this is for a path
|
|
89
97
|
s = "']['".join(key.split("/"))
|
|
90
98
|
s = "['" + s
|
|
@@ -109,7 +117,7 @@ class Transient(MutableMapping):
|
|
|
109
117
|
|
|
110
118
|
def __repr__(self, html=False):
|
|
111
119
|
if not html:
|
|
112
|
-
return
|
|
120
|
+
return f"Transient(\n\tName: {self.default_name},\n\tKeys: {self.keys()}\n)"
|
|
113
121
|
else:
|
|
114
122
|
html = ""
|
|
115
123
|
|
|
@@ -260,14 +268,17 @@ class Transient(MutableMapping):
|
|
|
260
268
|
# now return out as a Transient Object
|
|
261
269
|
return Transient(out)
|
|
262
270
|
|
|
263
|
-
def get_meta(self, keys=None):
|
|
271
|
+
def get_meta(self, keys=None) -> Self:
|
|
264
272
|
"""
|
|
265
273
|
Get the metadata (no photometry or spectra)
|
|
266
274
|
|
|
267
275
|
This essentially just wraps on __getitem__ but with some checks
|
|
268
276
|
|
|
269
277
|
Args:
|
|
270
|
-
keys
|
|
278
|
+
keys (list[str]) : list of keys to get the metadata for from the transient
|
|
279
|
+
|
|
280
|
+
Returns:
|
|
281
|
+
A Transient object of just the meta data
|
|
271
282
|
"""
|
|
272
283
|
if keys is None:
|
|
273
284
|
keys = list(self.keys())
|
|
@@ -296,9 +307,16 @@ class Transient(MutableMapping):
|
|
|
296
307
|
|
|
297
308
|
return self[keys]
|
|
298
309
|
|
|
299
|
-
def get_skycoord(self, coord_format="icrs"):
|
|
310
|
+
def get_skycoord(self, coord_format="icrs") -> SkyCoord:
|
|
300
311
|
"""
|
|
301
312
|
Convert the coordinates to an astropy SkyCoord
|
|
313
|
+
|
|
314
|
+
Args:
|
|
315
|
+
coord_format (str): Astropy coordinate format to convert the SkyCoord to
|
|
316
|
+
defaults to icrs.
|
|
317
|
+
|
|
318
|
+
Returns:
|
|
319
|
+
Astropy.coordinates.SkyCoord of the default coordinate for the transient
|
|
302
320
|
"""
|
|
303
321
|
|
|
304
322
|
# now we can generate the SkyCoord
|
|
@@ -309,9 +327,12 @@ class Transient(MutableMapping):
|
|
|
309
327
|
|
|
310
328
|
return coord
|
|
311
329
|
|
|
312
|
-
def get_discovery_date(self):
|
|
330
|
+
def get_discovery_date(self) -> Time:
|
|
313
331
|
"""
|
|
314
|
-
Get the default discovery date
|
|
332
|
+
Get the default discovery date for this Transient
|
|
333
|
+
|
|
334
|
+
Returns:
|
|
335
|
+
astropy.time.Time of the default discovery date
|
|
315
336
|
"""
|
|
316
337
|
key = "date_reference"
|
|
317
338
|
date = self._get_default(key, filt='df["date_type"] == "discovery"')
|
|
@@ -322,9 +343,12 @@ class Transient(MutableMapping):
|
|
|
322
343
|
|
|
323
344
|
return Time(date["value"], format=f)
|
|
324
345
|
|
|
325
|
-
def get_redshift(self):
|
|
346
|
+
def get_redshift(self) -> float:
|
|
326
347
|
"""
|
|
327
|
-
Get the default redshift
|
|
348
|
+
Get the default redshift of this Transient
|
|
349
|
+
|
|
350
|
+
Returns:
|
|
351
|
+
Float value of the default redshift
|
|
328
352
|
"""
|
|
329
353
|
f = "df['distance_type']=='redshift'"
|
|
330
354
|
default = self._get_default("distance", filt=f)
|
|
@@ -390,10 +414,32 @@ class Transient(MutableMapping):
|
|
|
390
414
|
wave_unit: u.Unit = "nm",
|
|
391
415
|
by: str = "raw",
|
|
392
416
|
obs_type: str = None,
|
|
393
|
-
):
|
|
417
|
+
) -> pd.DataFrame:
|
|
394
418
|
"""
|
|
395
419
|
Ensure the photometry associated with this transient is all in the same
|
|
396
420
|
units/system/etc
|
|
421
|
+
|
|
422
|
+
Args:
|
|
423
|
+
flux_unit (astropy.unit.Unit): The astropy unit or string representation of
|
|
424
|
+
an astropy unit to convert and return the
|
|
425
|
+
flux as.
|
|
426
|
+
date_unit (str): Valid astropy date format string.
|
|
427
|
+
freq_unit (astropy.unit.Unit): The astropy unit or string representation of
|
|
428
|
+
an astropy unit to convert and return the
|
|
429
|
+
frequency as.
|
|
430
|
+
wave_unit (astropy.unit.Unit): The astropy unit or string representation of
|
|
431
|
+
an astropy unit to convert and return the
|
|
432
|
+
wavelength as.
|
|
433
|
+
by (str): Either 'raw' or 'value'. 'raw' is the default and is highly
|
|
434
|
+
recommended! If 'value' is used it may skip some photometry.
|
|
435
|
+
See the schema definition to understand this keyword completely
|
|
436
|
+
before using it.
|
|
437
|
+
obs_type (str): "radio", "xray", or "uvoir". If provided, it only returns
|
|
438
|
+
data taken within that range of wavelengths/frequencies.
|
|
439
|
+
Default is None which will return all of the data.
|
|
440
|
+
|
|
441
|
+
Returns:
|
|
442
|
+
A pandas DataFrame of the cleaned up photometry in the requested units
|
|
397
443
|
"""
|
|
398
444
|
|
|
399
445
|
# check inputs
|
|
@@ -429,6 +475,9 @@ class Transient(MutableMapping):
|
|
|
429
475
|
else:
|
|
430
476
|
by = "value"
|
|
431
477
|
|
|
478
|
+
# skip rows where 'by' is nan
|
|
479
|
+
df = df[df[by].notna()]
|
|
480
|
+
|
|
432
481
|
# drop irrelevant obs_types before continuing
|
|
433
482
|
if obs_type is not None:
|
|
434
483
|
valid_obs_types = {"radio", "uvoir", "xray"}
|
|
@@ -6,19 +6,21 @@ Currently supported backends are:
|
|
|
6
6
|
- plotly
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
+
from __future__ import annotations
|
|
9
10
|
import importlib
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
class OtterPlotter:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Handles the backend for the "plotter" module
|
|
14
|
+
"""
|
|
15
|
+
Handles the backend for the "plotter" module
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
Args:
|
|
18
|
+
backend (string): a string of the module name to import and use
|
|
19
|
+
as the backend. Currently supported are "matplotlib",
|
|
20
|
+
"matplotlib.pyplot", "plotly", and "plotly.graph_objects"
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, backend):
|
|
22
24
|
if backend == "matplotlib.pyplot":
|
|
23
25
|
self.backend = backend
|
|
24
26
|
elif backend == "pyplot.graph_objects":
|