wintertoo 0.3.8__py3-none-any.whl → 0.4.2__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.

Potentially problematic release.


This version of wintertoo might be problematic. Click here for more details.

@@ -19,10 +19,12 @@ winter_fields_path = data_dir.joinpath("winter_fields.txt")
19
19
  winter_fields = pd.read_csv(winter_fields_path, sep=r"\s+")
20
20
 
21
21
  SummerFilters = Literal["u", "g", "r", "i"]
22
- WinterFilters = Literal["Y", "J", "Hs"]
22
+
23
+ WinterFilters = Literal["dark", "Y", "J", "Hs"]
23
24
 
24
25
  SUMMER_FILTERS = list(typing.get_args(SummerFilters))
25
26
  WINTER_FILTERS = list(typing.get_args(WinterFilters))
27
+ WINTER_SCIENCE_FILTERS = ["Y", "J", "Hs"]
26
28
 
27
29
  SUMMER_BASE_WIDTH = 0.26112
28
30
  WINTER_BASE_WIDTH = 1.0
@@ -4,7 +4,7 @@
4
4
  "obsHistID": {"type": "integer"},
5
5
  "raDeg": {"type": "number", "comment": "Degrees (decimal)"},
6
6
  "decDeg": {"type": "number", "comment": "Degrees (decimal)"},
7
- "filter": {"type": "string", "comment": "'u'/'g'/'r'/'i'/'Y'/'J'/'H'"},
7
+ "filter": {"type": "string", "comment": "'u'/'g'/'r'/'i'/'Y'/'J'/'H'/'dark'"},
8
8
  "visitExpTime": {"type": "number", "comment": "Total observation time (seconds)", "default": 30.0},
9
9
  "priority": {"type": "number", "comment": "Priority of observation"},
10
10
  "progPI": {"type": "string", "comment": "PI of observation"},
@@ -15,9 +15,9 @@
15
15
  "observed": {"anyOf": [{"type": "boolean", "default": false}, {"type" : "integer", "minimum" : 0, "maximum" : 1}]},
16
16
  "maxAirmass": {"type": "number", "comment": "Maximum airmass for observation", "default": 2.0},
17
17
  "ditherNumber": {"type": "integer", "default": 1},
18
- "ditherStepSize": {"type": "number", "comment": "arcsec", "default": 15.0},
18
+ "ditherStepSize": {"type": "number", "comment": "arcsec", "default": 600.0},
19
19
  "fieldID": {"type": "integer", "default": 999999999},
20
- "targName": {"type": "string", "comment": "Target name e.g. GW170817"}
20
+ "targName": {"type": ["string", "null"], "comment": "Target name e.g. GW170817"}
21
21
  },
22
22
  "required": [
23
23
  "obsHistID",
wintertoo/fields.py CHANGED
@@ -74,10 +74,11 @@ def get_fields_in_box(
74
74
  """
75
75
 
76
76
  field_df = get_fields(summer=summer)
77
+ base_width = 0.5 * get_base_width(summer=summer)
77
78
 
78
79
  res = field_df.query(
79
- f"(RA > {ra_lim[0]}) and (RA < {ra_lim[1]}) "
80
- f"and (Dec > {dec_lim[0]}) and (Dec < {dec_lim[1]})"
80
+ f"(RA > {ra_lim[0] - base_width}) and (RA < {ra_lim[1] + base_width}) "
81
+ f"and (Dec > {dec_lim[0] - base_width}) and (Dec < {dec_lim[1] + base_width})"
81
82
  )
82
83
  return res
83
84
 
wintertoo/models/image.py CHANGED
@@ -5,7 +5,7 @@ from typing import Literal
5
5
 
6
6
  from astropy import units as u
7
7
  from astropy.time import Time
8
- from pydantic import BaseModel, Field, validator
8
+ from pydantic import BaseModel, Field, FieldValidationInfo, field_validator
9
9
 
10
10
  from wintertoo.errors import WinterValidationError
11
11
  from wintertoo.models import ProgramCredentials
@@ -18,7 +18,7 @@ class BaseImageQuery(BaseModel):
18
18
  """
19
19
 
20
20
  program_list: list[ProgramCredentials] = Field(
21
- title="List of programs to search for", min_items=1
21
+ title="List of programs to search for", min_length=1
22
22
  )
23
23
  start_date: int = Field(
24
24
  title="Start date for images",
@@ -50,24 +50,23 @@ class RectangleImageQuery(BaseImageQuery):
50
50
  title="Minimum dec (degrees)", ge=-90.0, le=90.0, default=90.0
51
51
  )
52
52
 
53
- @validator("ra_max", "dec_max")
53
+ @field_validator("ra_max", "dec_max")
54
54
  @classmethod
55
- def validate_field_pairs(cls, field_value, values, field):
55
+ def validate_field_pairs(cls, value: float, info: FieldValidationInfo) -> float:
56
56
  """
57
57
  Validate that the max value is greater than the min value
58
58
 
59
- :param field_value: Value of the field
60
- :param values: values of all fields
61
- :param field: field name
59
+ :param value: field value
60
+ :param info: field validation info
62
61
  :return: validated field value
63
62
  """
64
- min_key = field.name.replace("max", "min")
65
- min_val = values[min_key]
66
- if not field_value > min_val:
63
+ min_key = info.field_name.replace("max", "min")
64
+ min_val = info.data[min_key]
65
+ if not value > min_val:
67
66
  raise WinterValidationError(
68
- f"{field.name} ({field_value}) not greater than {min_key} ({min_val})"
67
+ f"{info.field_name} ({value}) not greater than {min_key} ({min_val})"
69
68
  )
70
- return field_value
69
+ return value
71
70
 
72
71
 
73
72
  class ConeImageQuery(BaseImageQuery):
@@ -5,8 +5,9 @@ Duplicated (sorry) from mirar/pipelines/summer/models/program.py, to avoid
5
5
  an elaborate web of imports for WSP.
6
6
  """
7
7
  from datetime import date
8
+ from typing import Optional
8
9
 
9
- from pydantic import BaseModel, Extra, Field, validator
10
+ from pydantic import BaseModel, ConfigDict, Field, FieldValidationInfo, field_validator
10
11
 
11
12
 
12
13
  class ProgramCredentials(BaseModel):
@@ -23,7 +24,7 @@ class Program(ProgramCredentials):
23
24
  A pydantic model for a program database entry
24
25
  """
25
26
 
26
- puid: int = Field(default=None)
27
+ puid: Optional[int] = Field(default=None)
27
28
  progid: int = Field(default=1)
28
29
  pi_name: str = Field(min_length=1, example="Hubble", default=None)
29
30
  pi_email: str = Field(min_length=1, example="someone@institute.com", default=None)
@@ -34,31 +35,35 @@ class Program(ProgramCredentials):
34
35
  maxpriority: float = Field(description="Max priority")
35
36
  progtitle: str = Field(min_length=1, example="A program title", default=None)
36
37
 
37
- @validator("enddate")
38
+ @field_validator("enddate")
38
39
  @classmethod
39
- def check_date(cls, field_value, values):
40
+ def check_date(cls, enddate: date, info: FieldValidationInfo) -> date:
40
41
  """
41
42
  Ensure dates are correctly formatted
42
43
 
44
+ :param enddate: end date
45
+ :param info: field validation info
46
+ :return: end date
43
47
  """
44
- startdate = values["startdate"]
45
- assert field_value > startdate
46
- return field_value
48
+ startdate = info.data["startdate"]
49
+ assert enddate > startdate
50
+ return enddate
47
51
 
48
- @validator("hours_remaining")
52
+ @field_validator("hours_remaining")
49
53
  @classmethod
50
- def validate_time_allocation(cls, field_value, values):
54
+ def validate_time_allocation(
55
+ cls, hours_remaining: float, info: FieldValidationInfo
56
+ ) -> float:
51
57
  """
52
58
  Ensure that time remaining has a sensible value
53
59
 
54
- :param field_value: field value
55
- :param values: values
60
+ :param hours_remaining: hours remaining
61
+ :param info: field validation info
56
62
  :return: field value
57
63
  """
58
- total_time = values["hours_allocated"]
59
- assert not field_value > total_time
60
- assert not field_value < 0.0
61
- return field_value
64
+ total_time = info.data["hours_allocated"]
65
+ assert not hours_remaining > total_time
66
+ assert not hours_remaining < 0.0
67
+ return hours_remaining
62
68
 
63
- class Config: # pylint: disable=missing-class-docstring,too-few-public-methods
64
- extra = Extra.forbid
69
+ model_config = ConfigDict(extra="forbid")
wintertoo/models/too.py CHANGED
@@ -4,17 +4,27 @@ Models for ToO requests
4
4
  from typing import List, Optional, Union
5
5
 
6
6
  from astropy.time import Time
7
- from pydantic import BaseModel, Extra, Field, validator
7
+ from pydantic import (
8
+ BaseModel,
9
+ ConfigDict,
10
+ Field,
11
+ FieldValidationInfo,
12
+ field_validator,
13
+ model_validator,
14
+ )
8
15
 
9
16
  from wintertoo.data import (
10
17
  SUMMER_FILTERS,
11
- WINTER_FILTERS,
18
+ WINTER_SCIENCE_FILTERS,
12
19
  SummerFilters,
13
20
  WinterFilters,
14
21
  get_default_value,
15
22
  )
16
23
  from wintertoo.errors import WinterValidationError
17
24
 
25
+ MIN_EXPOSURE_TIME = 0.28
26
+ MAX_EXPOSURE_TIME = 300.0
27
+
18
28
 
19
29
  class ToORequest(BaseModel):
20
30
  """
@@ -29,9 +39,8 @@ class ToORequest(BaseModel):
29
39
  )
30
40
  t_exp: float = Field(
31
41
  default=get_default_value("visitExpTime"),
32
- title="Individual exposure time (s)",
42
+ title="Combined Exposure Time across dithers (s)",
33
43
  ge=1.0,
34
- le=300,
35
44
  )
36
45
  n_exp: int = Field(default=1, ge=1, title="Number of dither sets")
37
46
  n_dither: int = Field(
@@ -54,28 +63,54 @@ class ToORequest(BaseModel):
54
63
  title="Allowed airmass range",
55
64
  )
56
65
 
57
- @validator("end_time_mjd")
66
+ @field_validator("end_time_mjd")
58
67
  @classmethod
59
- def validate_field_pairs(cls, field_value, values, field):
68
+ def validate_field_pairs(
69
+ cls, end_time_mjd: float, info: FieldValidationInfo
70
+ ) -> float:
60
71
  """
61
72
  Field validator to ensure that the end time is greater than the start time
62
73
 
63
- :param field_value: value of the field
64
- :param values: values of all fields
65
- :param field: field name
74
+ :param end_time_mjd: field value
75
+ :param info: field validation info
66
76
  :return: validated field value
67
77
  """
68
- min_key = "start_time_mjd"
69
- start_time = values[min_key]
70
- if not field_value > start_time:
78
+ start_time = info.data["start_time_mjd"]
79
+ if not end_time_mjd > start_time:
71
80
  raise WinterValidationError(
72
- f"{field.name} ({field_value}) not "
73
- f"greater than {min_key} ({start_time})"
81
+ f"end_time_mjd ({end_time_mjd}) not "
82
+ f"greater than start_time_mjd ({start_time})"
74
83
  )
75
- return field_value
84
+ return end_time_mjd
85
+
86
+ @model_validator(mode="after")
87
+ def validate_t_exp(self):
88
+ """
89
+ Field validator to ensure that the exposure time is not too long
90
+
91
+ :return: Validated total exposure time per dither set
92
+ """
93
+ n_dithers = self.n_dither
94
+ t_exp = self.t_exp
95
+ t_per_dither = t_exp / n_dithers
96
+
97
+ if t_per_dither > MAX_EXPOSURE_TIME:
98
+ raise WinterValidationError(
99
+ f"t_exp ({t_exp}) is too long for {n_dithers} dithers. "
100
+ f"Max exposure time per dither is {MAX_EXPOSURE_TIME} s, "
101
+ f"while you have selected {t_per_dither} s per dither"
102
+ )
103
+
104
+ if t_per_dither < MIN_EXPOSURE_TIME:
105
+ raise WinterValidationError(
106
+ f"t_exp ({t_exp}) is too short for {n_dithers} dithers. "
107
+ f"Min exposure time per dither is {MIN_EXPOSURE_TIME} s, "
108
+ f"while you have selected {t_per_dither} s per dither"
109
+ )
110
+
111
+ return self
76
112
 
77
- class Config: # pylint: disable=missing-class-docstring,too-few-public-methods
78
- extra = Extra.forbid
113
+ model_config = ConfigDict(extra="forbid")
79
114
 
80
115
 
81
116
  class ObsWithRaDec(BaseModel):
@@ -124,7 +159,7 @@ class Summer(ToORequest):
124
159
  class Winter(ToORequest):
125
160
  """Winter ToO Request"""
126
161
 
127
- filters: list[WinterFilters] = WINTER_FILTERS
162
+ filters: list[WinterFilters] = WINTER_SCIENCE_FILTERS
128
163
 
129
164
 
130
165
  class SummerFieldToO(Summer, FieldToO):
wintertoo/schedule.py CHANGED
@@ -79,7 +79,7 @@ def build_schedule_list(
79
79
  too: FullTooRequest,
80
80
  program: Program,
81
81
  csv_save_file: str = None,
82
- ):
82
+ ) -> pd.DataFrame:
83
83
  """
84
84
  Generate a full schedule request for single target,
85
85
  with all of RA, Dec and Field ID provided
@@ -118,7 +118,7 @@ def schedule_ra_dec(
118
118
  else:
119
119
  field_id = get_default_value("fieldID")
120
120
 
121
- full_request = FullTooRequest(field_id=field_id, **too.dict())
121
+ full_request = FullTooRequest(field_id=field_id, **too.model_dump())
122
122
 
123
123
  schedule = make_schedule(
124
124
  toos=[full_request],
@@ -149,7 +149,7 @@ def schedule_field(
149
149
  ra_deg = float(field_details["RA"].iloc[0])
150
150
  dec_deg = float(field_details["Dec"].iloc[0])
151
151
 
152
- full_request = FullTooRequest(ra_deg=ra_deg, dec_deg=dec_deg, **too.dict())
152
+ full_request = FullTooRequest(ra_deg=ra_deg, dec_deg=dec_deg, **too.model_dump())
153
153
 
154
154
  schedule = make_schedule(
155
155
  toos=[full_request],
@@ -185,7 +185,7 @@ def concat_toos(
185
185
  program=program,
186
186
  )
187
187
  else:
188
- err = f"Unrecognised type {type(too)}"
188
+ err = f"Unrecognised type {type(too)} for {too}"
189
189
  logger.error(err)
190
190
  raise WinterValidationError(err)
191
191
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: wintertoo
3
- Version: 0.3.8
3
+ Version: 0.4.2
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
@@ -21,7 +21,7 @@ Classifier: Operating System :: MacOS
21
21
  Requires-Python: >=3.9
22
22
  Description-Content-Type: text/markdown
23
23
  License-File: LICENSE
24
- Requires-Dist: pandas (>=2.0.0)
24
+ Requires-Dist: pandas
25
25
  Requires-Dist: astropy
26
26
  Requires-Dist: astroplan
27
27
  Requires-Dist: matplotlib
@@ -29,15 +29,15 @@ Requires-Dist: numpy
29
29
  Requires-Dist: pytz
30
30
  Requires-Dist: jsonschema
31
31
  Requires-Dist: sqlalchemy
32
- Requires-Dist: pydantic
32
+ Requires-Dist: pydantic >=2.2.0
33
33
  Requires-Dist: pre-commit
34
34
  Requires-Dist: bcrypt
35
35
  Requires-Dist: psycopg
36
36
  Requires-Dist: psycopg-binary
37
37
  Provides-Extra: dev
38
- Requires-Dist: black (==23.3.0) ; extra == 'dev'
39
- Requires-Dist: isort (==5.12.0) ; extra == 'dev'
40
- Requires-Dist: pylint (==2.17.4) ; extra == 'dev'
38
+ Requires-Dist: black ==23.7.0 ; extra == 'dev'
39
+ Requires-Dist: isort ==5.12.0 ; extra == 'dev'
40
+ Requires-Dist: pylint ==2.17.5 ; extra == 'dev'
41
41
  Requires-Dist: coveralls ; extra == 'dev'
42
42
 
43
43
  # wintertoo
@@ -63,4 +63,5 @@ pip install wintertoo
63
63
  git clone git@github.com:winter-telescope/wintertoo.git
64
64
  cd wintertoo
65
65
  pip install --editable ".[dev]"
66
+ pre-commit install
66
67
  ```
@@ -0,0 +1,21 @@
1
+ wintertoo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ wintertoo/database.py,sha256=I-GP76aNmO1KDNbiEdpqsbHLVvTE791QwOqab6I_BHc,3019
3
+ wintertoo/errors.py,sha256=iAFcy0z3A3bCnkJmAt_P-77fPaPHFGS1JbrK6O2dCEM,223
4
+ wintertoo/fields.py,sha256=xxQs-dZeBeiqemOoTtL0iihyLwzDfrRS8Dqc9N73BfI,6028
5
+ wintertoo/schedule.py,sha256=jr6pOuA89Tlonm8bM0QinoHzGtHVgRLMv2z9TZdEF3c,5475
6
+ wintertoo/submit.py,sha256=0Ok3EiwSMB26Wp8c3Y3xfhd2MRWrWCuNpHTxwu8MbcM,2410
7
+ wintertoo/utils.py,sha256=BWgBZoSX5xfqURb2Nkvf3i6A_IcVYU2SoXFvp6ez7Xc,3306
8
+ wintertoo/validate.py,sha256=R8GwP8DmDTSeDGEGZ16yW_2jgZqGNxcSqjLFw0f8O9E,8963
9
+ wintertoo/data/__init__.py,sha256=XMHBEWA9_fioEFIbYZASV1t90JFi1gIAfNKyCRk2x54,1466
10
+ wintertoo/data/observing_request_schema.json,sha256=A79t4FzTeZQgK3kA_087LT2xpS7EaDcjkKtNUqAWoog,1603
11
+ wintertoo/data/summer_fields.txt,sha256=5Sc7MBUacelzaq1KHSLmfAyZ3WB5YifMNwKRjBRBcRk,52684603
12
+ wintertoo/data/winter_fields.txt,sha256=TxySQTmJXCCgaf-oC1gzOYQb2Vr26KEKdJxqrZHHet0,3529364
13
+ wintertoo/models/__init__.py,sha256=ZE3R3rCgijStd36IEs620NRP9R18Ay2CvYUZyJQvreA,234
14
+ wintertoo/models/image.py,sha256=l0gsXM68AvN5NkD1JGMbFZkLz2Qx4EjzSL9Z3YjoOes,2484
15
+ wintertoo/models/program.py,sha256=D3UyzkedmX5L5eM3wGY398GXf3v2g27b0FlHpnRCNhc,2145
16
+ wintertoo/models/too.py,sha256=ZQyX2ak2-EeUa_S6nEg6EZrjt6h4l5EtmZFVvmkxUOM,4885
17
+ wintertoo-0.4.2.dist-info/LICENSE,sha256=1-4yY2S7St-8Koy4JGheNG9QPkwff7831u2JITQ2oQs,1063
18
+ wintertoo-0.4.2.dist-info/METADATA,sha256=5qjocQ4uiVn3gllBbaab1TSkSciPGGXRtEq6N25gnH0,2499
19
+ wintertoo-0.4.2.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
20
+ wintertoo-0.4.2.dist-info/top_level.txt,sha256=6SMjMBzaNrD77erdCiVcRTrPZ-x98SDX43akRjWj4T8,10
21
+ wintertoo-0.4.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.40.0)
2
+ Generator: bdist_wheel (0.41.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,21 +0,0 @@
1
- wintertoo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- wintertoo/database.py,sha256=I-GP76aNmO1KDNbiEdpqsbHLVvTE791QwOqab6I_BHc,3019
3
- wintertoo/errors.py,sha256=iAFcy0z3A3bCnkJmAt_P-77fPaPHFGS1JbrK6O2dCEM,223
4
- wintertoo/fields.py,sha256=AX21FB0-qolcpsRYkIywd16CeX8W023Qq5g3rLmfVEo,5923
5
- wintertoo/schedule.py,sha256=_v1JMrMYzkgiX5YcnoGoCuCEYlPQh-RdNim1REHWE00,5437
6
- wintertoo/submit.py,sha256=0Ok3EiwSMB26Wp8c3Y3xfhd2MRWrWCuNpHTxwu8MbcM,2410
7
- wintertoo/utils.py,sha256=BWgBZoSX5xfqURb2Nkvf3i6A_IcVYU2SoXFvp6ez7Xc,3306
8
- wintertoo/validate.py,sha256=R8GwP8DmDTSeDGEGZ16yW_2jgZqGNxcSqjLFw0f8O9E,8963
9
- wintertoo/data/__init__.py,sha256=vVltDgj2leaWF1Awl4ohZqZzCr_OIZDccVx_2ZWSgfI,1415
10
- wintertoo/data/observing_request_schema.json,sha256=jGRpCT9GYAQr-V0IB1V4_noXvXSxN1fnz6p0fVb8l2s,1585
11
- wintertoo/data/summer_fields.txt,sha256=5Sc7MBUacelzaq1KHSLmfAyZ3WB5YifMNwKRjBRBcRk,52684603
12
- wintertoo/data/winter_fields.txt,sha256=TxySQTmJXCCgaf-oC1gzOYQb2Vr26KEKdJxqrZHHet0,3529364
13
- wintertoo/models/__init__.py,sha256=ZE3R3rCgijStd36IEs620NRP9R18Ay2CvYUZyJQvreA,234
14
- wintertoo/models/image.py,sha256=XJmS0HryoeS6YFU9zpI5QPEKh1tC_iIVmsq8638sNlc,2480
15
- wintertoo/models/program.py,sha256=VR5F7XfRVVkNp_ztxBTLQCDemTtpKIdefTxPu6gy7LQ,1915
16
- wintertoo/models/too.py,sha256=dAK4mT7j3cbO75uo0Z03e0uL78KFLPLVANQFaGExG6o,3825
17
- wintertoo-0.3.8.dist-info/LICENSE,sha256=1-4yY2S7St-8Koy4JGheNG9QPkwff7831u2JITQ2oQs,1063
18
- wintertoo-0.3.8.dist-info/METADATA,sha256=DxP4BCw21irMXeMLzqwP5ySfE1fc6h3DO2Y0EGI7_vc,2488
19
- wintertoo-0.3.8.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
20
- wintertoo-0.3.8.dist-info/top_level.txt,sha256=6SMjMBzaNrD77erdCiVcRTrPZ-x98SDX43akRjWj4T8,10
21
- wintertoo-0.3.8.dist-info/RECORD,,