wintertoo 1.1.0__tar.gz → 1.3.0__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 wintertoo might be problematic. Click here for more details.
- {wintertoo-1.1.0 → wintertoo-1.3.0}/PKG-INFO +1 -1
- {wintertoo-1.1.0 → wintertoo-1.3.0}/pyproject.toml +1 -1
- {wintertoo-1.1.0 → wintertoo-1.3.0}/tests/test_schedule.py +2 -1
- wintertoo-1.3.0/tests/testdata/test_schedule.json +1 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/wintertoo/data/__init__.py +5 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/wintertoo/data/observing_request_schema.json +2 -1
- {wintertoo-1.1.0 → wintertoo-1.3.0}/wintertoo/models/__init__.py +7 -0
- wintertoo-1.3.0/wintertoo/models/image.py +115 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/wintertoo/models/too.py +26 -1
- {wintertoo-1.1.0 → wintertoo-1.3.0}/wintertoo/schedule.py +2 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/wintertoo/submit.py +36 -5
- {wintertoo-1.1.0 → wintertoo-1.3.0}/wintertoo.egg-info/PKG-INFO +1 -1
- wintertoo-1.1.0/tests/testdata/test_schedule.json +0 -1
- wintertoo-1.1.0/wintertoo/models/image.py +0 -84
- {wintertoo-1.1.0 → wintertoo-1.3.0}/.github/dependabot.yml +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/.github/workflows/automerge.yml +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/.github/workflows/black.yml +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/.github/workflows/continuous_integration.yml +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/.github/workflows/isort.yml +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/.github/workflows/pylint.yml +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/.gitignore +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/.pre-commit-config.yaml +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/LICENSE +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/README.md +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/setup.cfg +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/tests/test_fields.py +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/wintertoo/__init__.py +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/wintertoo/data/summer_fields.txt +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/wintertoo/data/winter_fields.txt +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/wintertoo/database.py +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/wintertoo/errors.py +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/wintertoo/fields.py +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/wintertoo/models/program.py +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/wintertoo/utils.py +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/wintertoo/validate.py +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/wintertoo.egg-info/SOURCES.txt +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/wintertoo.egg-info/dependency_links.txt +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/wintertoo.egg-info/requires.txt +0 -0
- {wintertoo-1.1.0 → wintertoo-1.3.0}/wintertoo.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: wintertoo
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Author-email: Robert Stein <rdstein@caltech.edu>, Danielle Frostig <frostig@mit.edu>, Viraj Karambelkar <viraj@astro.caltech.edu>
|
|
5
5
|
License: MIT
|
|
6
6
|
Project-URL: homepage, https://github.com/winter-telescope/wintertoo
|
|
@@ -85,7 +85,8 @@ class TestSchedule(unittest.TestCase):
|
|
|
85
85
|
|
|
86
86
|
validate_schedule_with_program(schedule, program)
|
|
87
87
|
|
|
88
|
-
export_schedule_to_sqlitedb(schedule,
|
|
88
|
+
output_path = export_schedule_to_sqlitedb(schedule, test_data_dir)
|
|
89
|
+
output_path.unlink()
|
|
89
90
|
|
|
90
91
|
def test_schedule_utils(self):
|
|
91
92
|
"""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"targName":{"0":null,"1":null,"2":null,"3":null},"raDeg":{"0":173.7056754,"1":173.7056754,"2":173.7056754,"3":173.7056754},"decDeg":{"0":11.253441,"1":11.253441,"2":11.253441,"3":11.253441},"fieldID":{"0":999999999,"1":999999999,"2":999999999,"3":999999999},"filter":{"0":"u","1":"g","2":"r","3":"i"},"visitExpTime":{"0":30.0,"1":30.0,"2":30.0,"3":30.0},"priority":{"0":50.0,"1":50.0,"2":50.0,"3":50.0},"progPI":{"0":"Stein","1":"Stein","2":"Stein","3":"Stein"},"progName":{"0":"2021A000","1":"2021A000","2":"2021A000","3":"2021A000"},"progID":{"0":1,"1":1,"2":1,"3":1},"validStart":{"0":62721.1894969287,"1":62721.1894969287,"2":62721.1894969287,"3":62721.1894969287},"validStop":{"0":62722.1894969452,"1":62722.1894969452,"2":62722.1894969452,"3":62722.1894969452},"observed":{"0":false,"1":false,"2":false,"3":false},"maxAirmass":{"0":2.0,"1":2.0,"2":2.0,"3":2.0},"ditherNumber":{"0":1,"1":1,"2":1,"3":1},"ditherStepSize":{"0":30.0,"1":30.0,"2":30.0,"3":30.0},"bestDetector":{"0":true,"1":true,"2":true,"3":true},"obsHistID":{"0":0,"1":1,"2":2,"3":3}}
|
|
@@ -30,6 +30,11 @@ WINTER_SCIENCE_FILTERS = ["Y", "J", "Hs"]
|
|
|
30
30
|
SUMMER_BASE_WIDTH = 0.26112
|
|
31
31
|
WINTER_BASE_WIDTH = 1.0
|
|
32
32
|
|
|
33
|
+
MAX_TARGNAME_LEN = 30
|
|
34
|
+
|
|
35
|
+
WinterImageTypes = Literal["exposure", "raw", "science", "stack", "diff"]
|
|
36
|
+
DEFAULT_IMAGE_TYPE = "stack"
|
|
37
|
+
|
|
33
38
|
PROGRAM_DB_HOST = "jagati.caltech.edu"
|
|
34
39
|
|
|
35
40
|
too_schedule_config_path = data_dir.joinpath("observing_request_schema.json")
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"ditherNumber": {"type": "integer", "default": 1},
|
|
18
18
|
"ditherStepSize": {"type": "number", "comment": "arcsec", "default": 30.0},
|
|
19
19
|
"fieldID": {"type": "integer", "default": 999999999},
|
|
20
|
-
"targName": {"type": ["string", "null"], "comment": "Target name e.g. GW170817"}
|
|
20
|
+
"targName": {"type": ["string", "null"], "comment": "Target name e.g. GW170817", "default": null},
|
|
21
|
+
"bestDetector": {"type": "boolean", "comment": "Center Ra/Dec of target on best detector", "default": true}
|
|
21
22
|
},
|
|
22
23
|
"required": [
|
|
23
24
|
"obsHistID",
|
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
Models for the wintertoo
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from wintertoo.models.image import (
|
|
6
|
+
ConeImageQuery,
|
|
7
|
+
ImagePath,
|
|
8
|
+
ProgramImageQuery,
|
|
9
|
+
RectangleImageQuery,
|
|
10
|
+
TargetImageQuery,
|
|
11
|
+
)
|
|
5
12
|
from wintertoo.models.program import Program, ProgramCredentials
|
|
6
13
|
from wintertoo.models.too import (
|
|
7
14
|
AllTooClasses,
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base models for image queries
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
from astropy import units as u
|
|
8
|
+
from astropy.time import Time
|
|
9
|
+
from pydantic import BaseModel, Field, model_validator
|
|
10
|
+
|
|
11
|
+
from wintertoo.data import DEFAULT_IMAGE_TYPE, MAX_TARGNAME_LEN, WinterImageTypes
|
|
12
|
+
from wintertoo.errors import WinterValidationError
|
|
13
|
+
from wintertoo.utils import get_date
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ImagePath(BaseModel):
|
|
17
|
+
"""
|
|
18
|
+
Base model for image paths
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
path: str = Field(title="Path to image", min_length=1, example="path/to/image.fits")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ProgramImageQuery(BaseModel):
|
|
25
|
+
"""
|
|
26
|
+
Base model for image queries
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
program_name: str = Field(
|
|
30
|
+
title="Program to search for", min_length=1, examples=["2020A000", "2021B001"]
|
|
31
|
+
)
|
|
32
|
+
start_date: int = Field(
|
|
33
|
+
title="Start date for images",
|
|
34
|
+
le=get_date(Time.now()),
|
|
35
|
+
default=get_date(Time.now() - 30.0 * u.day),
|
|
36
|
+
examples=[get_date(Time.now() - 30.0 * u.day), "20230601"],
|
|
37
|
+
)
|
|
38
|
+
end_date: int = Field(
|
|
39
|
+
title="End date for images",
|
|
40
|
+
le=get_date(Time.now()),
|
|
41
|
+
default=get_date(Time.now()),
|
|
42
|
+
examples=[get_date(Time.now() - 30.0 * u.day), get_date(Time.now())],
|
|
43
|
+
)
|
|
44
|
+
kind: WinterImageTypes = Field(
|
|
45
|
+
default=DEFAULT_IMAGE_TYPE, example="raw/science/diff"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class TargetImageQuery(ProgramImageQuery):
|
|
50
|
+
"""
|
|
51
|
+
Model for image queries based on target name
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
target_name: Optional[str] = Field(
|
|
55
|
+
title="Name of target",
|
|
56
|
+
min_length=1,
|
|
57
|
+
max_length=MAX_TARGNAME_LEN,
|
|
58
|
+
examples=["SN2023ixf", "ZTF19aapreis"],
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class RectangleImageQuery(ProgramImageQuery):
|
|
63
|
+
"""
|
|
64
|
+
Model for image queries with a rectangular region
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
ra_min: float = Field(
|
|
68
|
+
title="Minimum RA (degrees)", ge=0.0, le=360.0, examples=[90.0, 180.0]
|
|
69
|
+
)
|
|
70
|
+
ra_max: float = Field(
|
|
71
|
+
title="Minimum RA (degrees)", ge=0.0, le=360.0, examples=[90.0, 180.0]
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
dec_min: float = Field(
|
|
75
|
+
title="Minimum dec (degrees)", ge=-90.0, le=90.0, examples=[-30.0, 10.0]
|
|
76
|
+
)
|
|
77
|
+
dec_max: float = Field(
|
|
78
|
+
title="Minimum dec (degrees)", ge=-90.0, le=90.0, examples=[-30.0, 10.0]
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
@model_validator(mode="after")
|
|
82
|
+
def validate_field_pairs(self):
|
|
83
|
+
"""
|
|
84
|
+
Validate that the max value is greater than the min value
|
|
85
|
+
|
|
86
|
+
:return: validated field value
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
pairs = [
|
|
90
|
+
(self.ra_min, self.ra_max, "RA"),
|
|
91
|
+
(self.dec_min, self.dec_max, "Dec"),
|
|
92
|
+
]
|
|
93
|
+
for min_val, max_val, label in pairs:
|
|
94
|
+
if max_val <= min_val:
|
|
95
|
+
raise WinterValidationError(
|
|
96
|
+
f"{label} range invalid: maximum value ({max_val}) not "
|
|
97
|
+
f"greater than minimum value({min_val})"
|
|
98
|
+
)
|
|
99
|
+
return self
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class ConeImageQuery(ProgramImageQuery):
|
|
103
|
+
"""
|
|
104
|
+
Model for image queries with a circular region
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
ra: float = Field(
|
|
108
|
+
title="Center RA (degrees)", ge=0.0, le=360.0, examples=[90.0, 180.0]
|
|
109
|
+
)
|
|
110
|
+
dec: float = Field(
|
|
111
|
+
title="Center dec (degrees)", ge=-90.0, le=90.0, examples=[-30.0, 10.0]
|
|
112
|
+
)
|
|
113
|
+
radius_deg: float = Field(
|
|
114
|
+
title="Search radius in degrees", ge=0.0, le=90.0, default=1.0
|
|
115
|
+
)
|
|
@@ -8,6 +8,7 @@ from astropy.time import Time
|
|
|
8
8
|
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
|
9
9
|
|
|
10
10
|
from wintertoo.data import (
|
|
11
|
+
MAX_TARGNAME_LEN,
|
|
11
12
|
SUMMER_FILTERS,
|
|
12
13
|
WINTER_SCIENCE_FILTERS,
|
|
13
14
|
SummerFilters,
|
|
@@ -31,6 +32,13 @@ class ToORequest(BaseModel):
|
|
|
31
32
|
title="Priority for target",
|
|
32
33
|
ge=0.0,
|
|
33
34
|
)
|
|
35
|
+
target_name: Optional[str] = Field(
|
|
36
|
+
title="Name of the target",
|
|
37
|
+
min_length=1,
|
|
38
|
+
max_length=MAX_TARGNAME_LEN,
|
|
39
|
+
examples=["SN2021abc", "ZTF19aapreis"],
|
|
40
|
+
default=get_default_value("targName"),
|
|
41
|
+
)
|
|
34
42
|
t_exp: float = Field(
|
|
35
43
|
default=get_default_value("visitExpTime"),
|
|
36
44
|
title="Combined Exposure Time across dithers (s)",
|
|
@@ -56,6 +64,10 @@ class ToORequest(BaseModel):
|
|
|
56
64
|
le=5,
|
|
57
65
|
title="Allowed airmass range",
|
|
58
66
|
)
|
|
67
|
+
use_best_detector: bool = Field(
|
|
68
|
+
default=get_default_value("bestDetector"),
|
|
69
|
+
title="Place ra/dec at the center of the best detector",
|
|
70
|
+
)
|
|
59
71
|
|
|
60
72
|
@model_validator(mode="after")
|
|
61
73
|
def validate_end_time(self):
|
|
@@ -116,9 +128,22 @@ class ObsWithRaDec(BaseModel):
|
|
|
116
128
|
)
|
|
117
129
|
use_field_grid: bool = Field(
|
|
118
130
|
title="boolean whether to select nearest field in grid for central ra/dec",
|
|
119
|
-
default=
|
|
131
|
+
default=False,
|
|
120
132
|
)
|
|
121
133
|
|
|
134
|
+
@model_validator(mode="after")
|
|
135
|
+
def validate_field_best_detector(self):
|
|
136
|
+
"""
|
|
137
|
+
Field validator to ensure that the end time is greater than the start time
|
|
138
|
+
|
|
139
|
+
:return: validated field value
|
|
140
|
+
"""
|
|
141
|
+
if self.use_best_detector & self.use_field_grid:
|
|
142
|
+
raise WinterValidationError(
|
|
143
|
+
"Cannot use both use_best_detector and use_field_grid"
|
|
144
|
+
)
|
|
145
|
+
return self
|
|
146
|
+
|
|
122
147
|
|
|
123
148
|
class ObsWithField(BaseModel):
|
|
124
149
|
"""
|
|
@@ -45,6 +45,7 @@ def make_schedule(
|
|
|
45
45
|
for filter_name in too.filters:
|
|
46
46
|
for _ in range(too.n_exp):
|
|
47
47
|
new = {
|
|
48
|
+
"targName": too.target_name,
|
|
48
49
|
"raDeg": too.ra_deg,
|
|
49
50
|
"decDeg": too.dec_deg,
|
|
50
51
|
"fieldID": too.field_id,
|
|
@@ -60,6 +61,7 @@ def make_schedule(
|
|
|
60
61
|
"maxAirmass": too.max_airmass,
|
|
61
62
|
"ditherNumber": too.n_dither,
|
|
62
63
|
"ditherStepSize": too.dither_distance,
|
|
64
|
+
"bestDetector": too.use_best_detector,
|
|
63
65
|
}
|
|
64
66
|
all_entries.append(new)
|
|
65
67
|
|
|
@@ -4,6 +4,7 @@ Module handling submission of ToO schedules
|
|
|
4
4
|
|
|
5
5
|
import logging
|
|
6
6
|
from datetime import datetime
|
|
7
|
+
from pathlib import Path
|
|
7
8
|
from typing import Optional
|
|
8
9
|
|
|
9
10
|
import pandas as pd
|
|
@@ -13,8 +14,27 @@ from wintertoo.validate import validate_schedule_df, validate_schedule_request
|
|
|
13
14
|
|
|
14
15
|
logger = logging.getLogger(__name__)
|
|
15
16
|
|
|
17
|
+
FILE_DATE_FORMAT = "%Y_%m_%d_%H_%M_%S"
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
|
|
20
|
+
def get_db_file_name(program_name: str, date: Optional[datetime] = None) -> str:
|
|
21
|
+
"""
|
|
22
|
+
Function to get the name of a database file
|
|
23
|
+
|
|
24
|
+
:param program_name: Name of program
|
|
25
|
+
:param date: Date to use
|
|
26
|
+
:return: String of database file name
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
if date is None:
|
|
30
|
+
date = datetime.now()
|
|
31
|
+
|
|
32
|
+
strf_time = date.strftime(FILE_DATE_FORMAT)
|
|
33
|
+
|
|
34
|
+
return f"request_{program_name}_{strf_time}.db"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def export_schedule_to_sqlitedb(schedule: pd.DataFrame, base_save_path: str) -> Path:
|
|
18
38
|
"""
|
|
19
39
|
Function to export a schedule to an sqlite db file
|
|
20
40
|
|
|
@@ -25,17 +45,26 @@ def export_schedule_to_sqlitedb(schedule: pd.DataFrame, base_save_path: str):
|
|
|
25
45
|
# Validate format of schedule using json schema
|
|
26
46
|
validate_schedule_df(schedule)
|
|
27
47
|
|
|
28
|
-
|
|
48
|
+
program_name = str(schedule["progName"].iloc[0])
|
|
49
|
+
|
|
50
|
+
schedule_file_name = get_db_file_name(program_name=program_name)
|
|
29
51
|
|
|
30
|
-
save_path =
|
|
52
|
+
save_path = Path(base_save_path).joinpath(schedule_file_name)
|
|
31
53
|
|
|
32
54
|
logger.info(f"Saving to {save_path}")
|
|
33
55
|
|
|
34
56
|
sqlite_table = "Summary"
|
|
35
57
|
|
|
58
|
+
if not save_path.parent.exists():
|
|
59
|
+
err = f"Parent directory {save_path.parent} does not exist"
|
|
60
|
+
logger.error(err)
|
|
61
|
+
raise ValueError(err)
|
|
62
|
+
|
|
36
63
|
engine = create_engine(f"sqlite:///{save_path}?check_same_thread=False", echo=True)
|
|
37
64
|
schedule.to_sql(sqlite_table, engine, if_exists="replace", index=False)
|
|
38
65
|
|
|
66
|
+
return save_path
|
|
67
|
+
|
|
39
68
|
|
|
40
69
|
def submit_schedule( # pylint: disable=too-many-arguments
|
|
41
70
|
schedule: pd.DataFrame,
|
|
@@ -47,7 +76,7 @@ def submit_schedule( # pylint: disable=too-many-arguments
|
|
|
47
76
|
program_db_password: str,
|
|
48
77
|
save_path: Optional[str] = None,
|
|
49
78
|
submit_trigger: bool = True,
|
|
50
|
-
):
|
|
79
|
+
) -> Optional[Path]:
|
|
51
80
|
"""
|
|
52
81
|
Function to validate, and then optionally submit, a schedule
|
|
53
82
|
|
|
@@ -77,4 +106,6 @@ def submit_schedule( # pylint: disable=too-many-arguments
|
|
|
77
106
|
logger.error(err)
|
|
78
107
|
raise ValueError(err)
|
|
79
108
|
|
|
80
|
-
export_schedule_to_sqlitedb(schedule, save_path)
|
|
109
|
+
return export_schedule_to_sqlitedb(schedule, save_path)
|
|
110
|
+
|
|
111
|
+
return None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: wintertoo
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Author-email: Robert Stein <rdstein@caltech.edu>, Danielle Frostig <frostig@mit.edu>, Viraj Karambelkar <viraj@astro.caltech.edu>
|
|
5
5
|
License: MIT
|
|
6
6
|
Project-URL: homepage, https://github.com/winter-telescope/wintertoo
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"raDeg":{"0":173.60947,"1":173.60947,"2":173.60947,"3":173.60947},"decDeg":{"0":11.16715,"1":11.16715,"2":11.16715,"3":11.16715},"fieldID":{"0":244641,"1":244641,"2":244641,"3":244641},"filter":{"0":"u","1":"g","2":"r","3":"i"},"visitExpTime":{"0":30.0,"1":30.0,"2":30.0,"3":30.0},"priority":{"0":50.0,"1":50.0,"2":50.0,"3":50.0},"progPI":{"0":"Stein","1":"Stein","2":"Stein","3":"Stein"},"progName":{"0":"2021A000","1":"2021A000","2":"2021A000","3":"2021A000"},"progID":{"0":1,"1":1,"2":1,"3":1},"validStart":{"0":62721.1894969287,"1":62721.1894969287,"2":62721.1894969287,"3":62721.1894969287},"validStop":{"0":62722.1894969452,"1":62722.1894969452,"2":62722.1894969452,"3":62722.1894969452},"observed":{"0":false,"1":false,"2":false,"3":false},"maxAirmass":{"0":2.0,"1":2.0,"2":2.0,"3":2.0},"ditherNumber":{"0":1,"1":1,"2":1,"3":1},"ditherStepSize":{"0":30.0,"1":30.0,"2":30.0,"3":30.0},"obsHistID":{"0":0,"1":1,"2":2,"3":3}}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Base models for image queries
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from typing import Literal
|
|
6
|
-
|
|
7
|
-
from astropy import units as u
|
|
8
|
-
from astropy.time import Time
|
|
9
|
-
from pydantic import BaseModel, Field, model_validator
|
|
10
|
-
|
|
11
|
-
from wintertoo.errors import WinterValidationError
|
|
12
|
-
from wintertoo.models import ProgramCredentials
|
|
13
|
-
from wintertoo.utils import get_date
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class BaseImageQuery(BaseModel):
|
|
17
|
-
"""
|
|
18
|
-
Base model for image queries
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
program_list: list[ProgramCredentials] = Field(
|
|
22
|
-
title="List of programs to search for", min_length=1
|
|
23
|
-
)
|
|
24
|
-
start_date: int = Field(
|
|
25
|
-
title="Start date for images",
|
|
26
|
-
le=get_date(Time.now()),
|
|
27
|
-
default=get_date(Time.now() - 30.0 * u.day),
|
|
28
|
-
)
|
|
29
|
-
end_date: int = Field(
|
|
30
|
-
title="End date for images",
|
|
31
|
-
le=get_date(Time.now()),
|
|
32
|
-
default=get_date(Time.now()),
|
|
33
|
-
)
|
|
34
|
-
kind: Literal["raw", "science", "diff"] = Field(
|
|
35
|
-
default="science", title="raw/science/diff"
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
class RectangleImageQuery(BaseImageQuery):
|
|
40
|
-
"""
|
|
41
|
-
Model for image queries with a rectangular region
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
ra_min: float = Field(title="Minimum RA (degrees)", ge=0.0, le=360.0, default=0.0)
|
|
45
|
-
ra_max: float = Field(title="Minimum RA (degrees)", ge=0.0, le=360.0, default=360.0)
|
|
46
|
-
|
|
47
|
-
dec_min: float = Field(
|
|
48
|
-
title="Minimum dec (degrees)", ge=-90.0, le=90.0, default=-90.0
|
|
49
|
-
)
|
|
50
|
-
dec_max: float = Field(
|
|
51
|
-
title="Minimum dec (degrees)", ge=-90.0, le=90.0, default=90.0
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
@model_validator(mode="after")
|
|
55
|
-
def validate_field_pairs(self):
|
|
56
|
-
"""
|
|
57
|
-
Validate that the max value is greater than the min value
|
|
58
|
-
|
|
59
|
-
:return: validated field value
|
|
60
|
-
"""
|
|
61
|
-
|
|
62
|
-
pairs = [
|
|
63
|
-
(self.ra_min, self.ra_max, "RA"),
|
|
64
|
-
(self.dec_min, self.dec_max, "Dec"),
|
|
65
|
-
]
|
|
66
|
-
for min_val, max_val, label in pairs:
|
|
67
|
-
if max_val <= min_val:
|
|
68
|
-
raise WinterValidationError(
|
|
69
|
-
f"{label} range invalid: maximum value ({max_val}) not "
|
|
70
|
-
f"greater than minimum value({min_val})"
|
|
71
|
-
)
|
|
72
|
-
return self
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
class ConeImageQuery(BaseImageQuery):
|
|
76
|
-
"""
|
|
77
|
-
Model for image queries with a circular region
|
|
78
|
-
"""
|
|
79
|
-
|
|
80
|
-
ra: float = Field(title="Center RA (degrees)", ge=0.0, le=360.0, default=0.0)
|
|
81
|
-
dec: float = Field(title="Center dec (degrees)", ge=-90.0, le=90.0, default=-90.0)
|
|
82
|
-
radius_deg: float = Field(
|
|
83
|
-
title="Search radius in degrees", ge=0.0, le=90.0, default=1.0
|
|
84
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|