wintertoo 1.1.0__tar.gz → 1.2.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.

Files changed (39) hide show
  1. {wintertoo-1.1.0 → wintertoo-1.2.0}/PKG-INFO +1 -1
  2. {wintertoo-1.1.0 → wintertoo-1.2.0}/pyproject.toml +1 -1
  3. {wintertoo-1.1.0 → wintertoo-1.2.0}/tests/test_schedule.py +2 -1
  4. wintertoo-1.2.0/tests/testdata/test_schedule.json +1 -0
  5. {wintertoo-1.1.0 → wintertoo-1.2.0}/wintertoo/data/__init__.py +5 -0
  6. {wintertoo-1.1.0 → wintertoo-1.2.0}/wintertoo/data/observing_request_schema.json +1 -1
  7. {wintertoo-1.1.0 → wintertoo-1.2.0}/wintertoo/models/__init__.py +7 -0
  8. wintertoo-1.2.0/wintertoo/models/image.py +115 -0
  9. {wintertoo-1.1.0 → wintertoo-1.2.0}/wintertoo/models/too.py +9 -1
  10. {wintertoo-1.1.0 → wintertoo-1.2.0}/wintertoo/schedule.py +1 -0
  11. {wintertoo-1.1.0 → wintertoo-1.2.0}/wintertoo/submit.py +36 -5
  12. {wintertoo-1.1.0 → wintertoo-1.2.0}/wintertoo.egg-info/PKG-INFO +1 -1
  13. wintertoo-1.1.0/tests/testdata/test_schedule.json +0 -1
  14. wintertoo-1.1.0/wintertoo/models/image.py +0 -84
  15. {wintertoo-1.1.0 → wintertoo-1.2.0}/.github/dependabot.yml +0 -0
  16. {wintertoo-1.1.0 → wintertoo-1.2.0}/.github/workflows/automerge.yml +0 -0
  17. {wintertoo-1.1.0 → wintertoo-1.2.0}/.github/workflows/black.yml +0 -0
  18. {wintertoo-1.1.0 → wintertoo-1.2.0}/.github/workflows/continuous_integration.yml +0 -0
  19. {wintertoo-1.1.0 → wintertoo-1.2.0}/.github/workflows/isort.yml +0 -0
  20. {wintertoo-1.1.0 → wintertoo-1.2.0}/.github/workflows/pylint.yml +0 -0
  21. {wintertoo-1.1.0 → wintertoo-1.2.0}/.gitignore +0 -0
  22. {wintertoo-1.1.0 → wintertoo-1.2.0}/.pre-commit-config.yaml +0 -0
  23. {wintertoo-1.1.0 → wintertoo-1.2.0}/LICENSE +0 -0
  24. {wintertoo-1.1.0 → wintertoo-1.2.0}/README.md +0 -0
  25. {wintertoo-1.1.0 → wintertoo-1.2.0}/setup.cfg +0 -0
  26. {wintertoo-1.1.0 → wintertoo-1.2.0}/tests/test_fields.py +0 -0
  27. {wintertoo-1.1.0 → wintertoo-1.2.0}/wintertoo/__init__.py +0 -0
  28. {wintertoo-1.1.0 → wintertoo-1.2.0}/wintertoo/data/summer_fields.txt +0 -0
  29. {wintertoo-1.1.0 → wintertoo-1.2.0}/wintertoo/data/winter_fields.txt +0 -0
  30. {wintertoo-1.1.0 → wintertoo-1.2.0}/wintertoo/database.py +0 -0
  31. {wintertoo-1.1.0 → wintertoo-1.2.0}/wintertoo/errors.py +0 -0
  32. {wintertoo-1.1.0 → wintertoo-1.2.0}/wintertoo/fields.py +0 -0
  33. {wintertoo-1.1.0 → wintertoo-1.2.0}/wintertoo/models/program.py +0 -0
  34. {wintertoo-1.1.0 → wintertoo-1.2.0}/wintertoo/utils.py +0 -0
  35. {wintertoo-1.1.0 → wintertoo-1.2.0}/wintertoo/validate.py +0 -0
  36. {wintertoo-1.1.0 → wintertoo-1.2.0}/wintertoo.egg-info/SOURCES.txt +0 -0
  37. {wintertoo-1.1.0 → wintertoo-1.2.0}/wintertoo.egg-info/dependency_links.txt +0 -0
  38. {wintertoo-1.1.0 → wintertoo-1.2.0}/wintertoo.egg-info/requires.txt +0 -0
  39. {wintertoo-1.1.0 → wintertoo-1.2.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.1.0
3
+ Version: 1.2.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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "wintertoo"
7
- version = "1.1.0"
7
+ version = "1.2.0"
8
8
  description = ""
9
9
  authors = [
10
10
  {name = "Robert Stein", email = "rdstein@caltech.edu"},
@@ -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, "test_schedule.db")
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},"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,7 @@
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
21
  },
22
22
  "required": [
23
23
  "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)",
@@ -116,7 +124,7 @@ class ObsWithRaDec(BaseModel):
116
124
  )
117
125
  use_field_grid: bool = Field(
118
126
  title="boolean whether to select nearest field in grid for central ra/dec",
119
- default=True,
127
+ default=False,
120
128
  )
121
129
 
122
130
 
@@ -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,
@@ -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
- def export_schedule_to_sqlitedb(schedule: pd.DataFrame, base_save_path: str):
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
- date = datetime.now().strftime("%m_%d_%Y_%H_%s")
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 = f"{base_save_path}timed_requests_{date}.db"
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.1.0
3
+ Version: 1.2.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